WebSocket協議
Websocket協議具有生命週期,在生命週期由Websocket協議進行支撐。例如,在Servlet技術中,底層協議僅僅定義了簡單的請求/響應交互,此交互完全獨立於下一次交互。事實上,在大部分情況下攜帶交互數據的底層網絡連接將被完全弱化。一些技術必須請求/響應交互模型之上構建會話,這有助於開發人員創建比單一的隔離的交互生存時間更長的應用。
Websocket協議定義了客戶端和服務器間長時間存活的專用的TCP連接的正因爲如此,在定義更長時間的生命週期方面,它比傳統的Web請求/響應更快一步。此外,WebSocket協議定義了WebSocket連接上往返傳輸的數據的各個塊的格式。一旦連接已經建立,這些傳輸的元數據描述了其用途。WebSocket協議中包含兩種主要類型的幀:控制幀和數據幀。控制幀是用於執行協議的一些內部功能邏輯的數據傳輸,它意味着發送者準備關閉連接。其他控制幀是Ping幀和Pong幀。Ping幀和Pong幀是用來服務於連接健康性檢測的數據傳輸。如果WebSocke希望檢查其他WebSocket對等節點的連接的健康性,它可以發送Ping幀。當WebSocket對等節點收到Ping幀後,必須響應Pong幀。通乒乓球遊戲一樣,連接的健康性可以在任何時候進行檢測。
WebSocket協議定義的另一類幀是數據幀。數據幀定義了攜帶應用數據的WebSocket傳輸的種類。數據幀分爲兩種基本類型:文本型和二進制型,一種是用來攜帶文本消息,另一種用來攜帶二進制數據。
JAVA API中webSocket的生命週期
- 打開事件:此事件發生在端點上建立新連接時並且在任何其他事件發生之前。
- 消息事件:此事件接收WebSocket對話中另一端發送的消息。它可以發生在WebSocket端點接收了打開事件之後並且在接收關閉事件關閉連接之前的任意時刻。
- 錯誤事件:此事件在WebSocket連接或者端點發生錯誤時產生。
- 關閉事件:此事件表示WebSocket端點的連接目前正在部分地關閉,它可以由參與連接的任意一個端點發出。
下面用一個JAVADemo實現服務器端和客戶端的WebSokcet傳送
Server代碼:
package Echo;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);//設置服務監聽端口
System.out.println("等待客戶端連接...");//打印提示信息
Socket clientSocket = serverSocket.accept();//等待客戶端連接
Scanner scanner = new Scanner(clientSocket.getInputStream());//客戶端輸入流
scanner.useDelimiter("\n");//設置分隔符
PrintStream outPrintStream = new PrintStream(clientSocket.getOutputStream());//客戶端輸出流
boolean flag = true;//循環標記
while (flag) {
if(scanner.hasNext()) {//有數據接收
String string = scanner.next().trim();//接收數據內容
if("bye".equalsIgnoreCase(string)) {//結束標記
outPrintStream.println("Bye!");//迴應信息
flag = false;//結束循環
}else {
outPrintStream.println("[ECHO]" + string);//Echo信息
}
}
}
scanner.close();//關閉輸入流
outPrintStream.close();//關閉輸出流
clientSocket.close();//關閉客戶端
serverSocket.close();//關閉服務端
}
}
Client端代碼:
package Echo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));
public static String getString(String prompt) throws Exception{//鍵盤信息輸入
System.out.print(prompt);
String string = KEYBOARD_INPUT.readLine();
return string;
}
public static void main(String[] args) throws Exception{
Socket clientSocket = new Socket("localhost", 8888);//定義服務端的連接信息
//現在的客戶端需要有輸入與輸出的操作支持,所以依然要準備Scanner與PrintWriter
Scanner scanner = new Scanner(clientSocket.getInputStream());//接收服務端輸入內容
scanner.useDelimiter("\n");
PrintStream outputPrintStream = new PrintStream(clientSocket.getOutputStream());//向服務端發送內容
boolean flag = true;//循環標記
while(flag) {//循環處理
String inputString = getString("請輸入內容:").trim();//獲取鍵盤輸入數據
outputPrintStream.println(inputString);//加換行
if(scanner.hasNext()) {//服務器端有迴應
System.out.println(scanner.next());//輸出迴應信息
}
if("bye".equalsIgnoreCase(inputString)) {//結束判斷
flag = false;//修改循環標記
}
}
scanner.close();//關閉輸入流
outputPrintStream.close();//關閉輸出流
clientSocket.close();//關閉客戶端
}
}