Detailed WebSocket: technical principles, code demonstrations and application cases

1. Introduction

This article will briefly introduce the origin, principle, mechanism and server/client implementation of WebSocket, and guide and explain how to use WebSocket to solve real-time response and server-side message push problems with actual customer cases. This article is suitable for readers who are familiar with HTML protocol specifications and J2EE Web programming, and aims to help readers quickly become familiar with the principles and development applications of HTML5 WebSocket.

2. WebSocket past and present

As we all know, the interaction process of Web applications is usually that the client sends a request through the browser. The server receives the request and processes it and returns the result to the client. The client browser displays the information. This mechanism is not particularly frequent for information changes. The application is acceptable, but it is too difficult for applications with high real-time requirements and massive concurrency. Especially in the current trend of mobile Internet development in the industry, high concurrency and real-time user response are problems that Web applications often face, such as real-time financial securities Information, geographic location acquisition in web navigation applications, real-time news push of social networks, etc. The traditional request-response model of Web development usually uses real-time communication solutions when dealing with such business scenarios. The common ones are:

Polling: The principle is simple and easy to understand, that is, the client sends requests to the server in a certain time interval with frequent requests to keep the data synchronization between the client and the server. The problem is obvious. When the client sends a request to the server at a fixed frequency, the data on the server may not be updated, causing a lot of unnecessary requests, wasting bandwidth, and inefficient.

Based on Flash: AdobeFlash completes data exchange through its own Socket, and then uses Flash to expose the corresponding interface for JavaScript calls, so as to achieve real-time transmission. This method is more efficient than polling, and because of the high Flash installation rate, the application scenarios are more extensive, but the Flash support on mobile Internet terminals is not good. There is no Flash in the IOS system. Although there is Flash support in Android, the actual use effect is not satisfactory, and the hardware configuration requirements of mobile devices are high. In 2012, Adobe officially announced that it no longer supports the Android4.1+ system, announcing the death of Flash on mobile terminals.

As can be seen from the above, the traditional Web mode will encounter insurmountable bottlenecks when dealing with high concurrency and real-time requirements. We need an efficient and energy-saving two-way communication mechanism to ensure real-time data transmission. In this context, WebSocket, known as Web TCP, based on the HTML5 specification came into being. Early HTML5 did not form a unified industry specification. Various browser and application server vendors had different similar implementations, such as IBM’s MQTT and Comet open source framework. Until 2014, HTML5 was promoted and promoted by giants such as IBM, Microsoft, and Google. The dust finally landed under the cooperation, and the draft was officially implemented into the actual standard specification. Each application server and browser manufacturer gradually began to unify, and the WebSocket protocol was also implemented in JavaEE7, so that both the client and server WebSocket are complete, and readers can Check the HTML5 specification, and be familiar with the new HTML protocol specification and WebSocket support.

3. WebSocket mechanism

The following briefly introduces the principle and operating mechanism of WebSocket. WebSocket is a new protocol of HTML5. It implements full-duplex communication between the browser and the server, which can better save server resources and bandwidth and achieve real-time communication. It is built on TCP and transmits data through TCP like HTTP, but the biggest difference between it and HTTP is:

WebSocket is a two-way communication protocol. After a connection is established, both the WebSocket server and Browser/Client Agent can actively send or receive data to each other, just like Socket;

WebSocket requires a TCP-like client and server to connect through a handshake, and they can communicate with each other after the connection is successful.

The interaction between traditional HTTP client and server in non-WebSocket mode is shown in the following figure:Insert picture description here

The interaction between the client and the server using the WebSocket mode is as follows:
Insert picture description here
the comparison of the above figure shows that, compared to the traditional HTTP mode that each request-response requires the client to establish a connection with the server, WebSocket is a TCP long-connection communication similar to Socket Mode, once the WebSocket connection is established, subsequent data is transmitted in the form of a sequence of frames. Before the client disconnects the WebSocket connection or the server disconnects, there is no need for the client and server to initiate a connection request again. In the case of massive concurrency and high load traffic between the client and the server, it greatly saves the consumption of network bandwidth resources and has obvious performance advantages. The client sends and receives messages on the same persistent connection. The sexual advantage is obvious. Let's look at the difference between WebSocket communication and traditional HTTP through the messages exchanged between the client and the server. On the client side, new WebSocket instantiates a new WebSocket client object, and connects to the server WebSocket URL similar to ws://yourdomain:port/path. The WebSocket client object will be automatically parsed and recognized as a WebSocket request to connect to the server. Port, perform the handshake process between the two parties. The data format sent by the client is similar to the following:

GET /webfin/websocket/ HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost:8080
Sec-WebSocket-Version: 13

It can be seen that the WebSocket connection message initiated by the client is similar to the traditional HTTP message. The "Upgrade: websocket" parameter value indicates that this is a WebSocket type request, and the "Sec-WebSocket-Key" is a base64-encoded secret sent by the WebSocket client. This text requires the server to return a corresponding encrypted "Sec-WebSocket-Accept" response, otherwise the client will throw an "Error during WebSocket handshake" error and close the connection. The data format returned by the server after receiving the message is similar to the following:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

The value of "Sec-WebSocket-Accept" is calculated by the server using the same key as the client and then returned to the client. "HTTP/1.1 101 Switching Protocols" means that the server accepts the client connection of the WebSocket protocol, after such a request -After the response is processed, the WebSocket connection handshake between the client and the server is successful, and TCP communication can be carried out subsequently. Readers can refer to the WebSocket protocol stack to understand the more detailed interactive data format of the WebSocket client and server. In terms of development, the WebSocket API is also very simple. We only need to instantiate the WebSocket, create a connection, and then the server and client can send and respond to each other messages. In the WebSocket implementation and case analysis section below, you can see the detailed WebSocket API And code implementation.

4. WebSocket implementation

As mentioned above, the implementation of WebSocket is divided into two parts: the client and the server. The client (usually a browser) sends out a WebSocket connection request, and the server responds to achieve a TCP handshake action, so that the browser client and WebSocket A fast HTTP long connection is formed between the servers. Subsequent direct data transfer between the two will eliminate the need to initiate a connection and response. The following briefly describes the WebSocket server API and client API.

4.1 WebSocket server API

The WebSocket server has basically obtained the support of the API that conforms to the JEE JSR356 standard specification among the mainstream application server vendors (see the JSR356 WebSocket API specification for details). The following lists the support of some common commercial and open source application servers on the WebSocket Server:Insert picture description here

Below we use the Tomcat7.0.5 version of the server-side sample code to illustrate the implementation of the WebSocket server. The WebSocket specification of JSR356 uses the API of javax.websocket.*, and an ordinary Java object (POJO) can be annotated with @ServerEndpoint as the endpoint of the WebSocket server. The code example is as follows. WebSocket server API example:

@ServerEndpoint("/echo")
public class EchoEndpoint {
@OnOpen
public void onOpen(Session session) throws IOException {
//以下代码省略…
}

  @OnMessage
  public String onMessage(String message) {
       //以下代码省略...
  }

  @Message(maxMessageSize=6)
  public void receiveMessage(String s) {
       //以下代码省略...
  }

  @OnError
  public void onError(Throwable t) {
       //以下代码省略...
  }

  @OnClose
  public void onClose(Session session, CloseReason reason) {
       //以下代码省略...
  }

}

Code explanation: The above concise code establishes a WebSocket server. The annotation endpoint of @ServerEndpoint("/echo") means that the WebSocket server runs on ws://[Server IP or domain name]:[Server The access endpoint of port]/websockets/echo, the client browser can initiate an HTTP persistent connection to the WebSocket client API. The class annotated with ServerEndpoint must have a public no-parameter constructor. The Java method annotated with @onMessage is used to receive the incoming WebSocket information. This information can be in text or binary format. OnOpen is called when a new connection is established at this endpoint. Parameters provide more details on the other end of the connection. Session indicates the other end of the connection between two WebSocket endpoints, which can be understood as a concept similar to HTTPSession. OnClose is called when the connection is terminated. The parameter closeReason can encapsulate more details, such as why a WebSocket connection is closed. More advanced customization such as @Message annotation, MaxMessageSize property can be used to define the maximum limit of message bytes, in the sample program, if more than 6 bytes of information are received, an error is reported and the connection is closed. Note: In the early days, different application servers supported different WebSocket methods. Even the same manufacturer, different versions have subtle differences. For example, Tomcat server 7.0.5 and above are all implemented by the standard JSR356 specification, while the 7.0.2x/7.0.3X version Use custom APIs (WebSocketServlet and StreamInbound, the former is a container to initialize the WebSocket environment; the latter is used to process WebSocket requests and responses, see the case analysis section for details), and Tomcat7.0.3x and 7.0. The definition of 2x's createWebSocketInbound method is different, an HttpServletRequest parameter is added, so that more WebSocket client information can be obtained from the request parameter, as shown in the following code. Tomcat7.0.3X version WebSocket API:

public class EchoServlet extends WebSocketServlet {
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) {
//以下代码省略…
return new MessageInbound() {
protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
//以下代码省略…
}

           protected void onTextMessage(CharBuffer buffer) throws IOException {
           getWsOutbound().writeTextMessage(buffer);
           //以下代码省略...
       }
 };

}
}

Therefore, the server side that chooses WebSocket needs to choose its version. Normally, the newer version supports the standard JSR specification API for WebSocket, but the ease of development and the portability of the old version of the program should also be considered, as follows The customer case described is the Tomcat 7.0.3X version of the WebSocketServlet implementation that is used because the customer requires a unified application server version instead of the JSR356 @ServerEndpoint annotation endpoint.

4.2 WebSocket client API

For WebSocket clients, mainstream browsers (including PCs and mobile terminals) now support the standard HTML5 WebSocket API, which means that the client’s WebSocket JavaScirpt script has good consistency and cross-platform features. The following are common Browser vendors’ support for WebSocket. WebSocket browser support: The
Insert picture description here
client-side WebSocket API has basically been unified among all major browser manufacturers, so it is enough to use the standard HTML5 defined WebSocket client-side JavaScript API. Of course, you can also use the industry’s open source framework that meets the WebSocket standards and specifications. Such as Socket.io. The following is a code example to illustrate the client implementation of WebSocket. WebSocket client API example:

var ws = new WebSocket(“ws://echo.websocket.org”);
ws.onopen = function(){ws.send(“Test!”); };
ws.onmessage = function(evt){console.log(evt.data);ws.close();};
ws.onclose = function(evt){console.log(“WebSocketClosed!”);};
ws.onerror = function(evt){console.log(“WebSocketError!”);};

The first line of code is applying for a WebSocket object, and the parameter is the address of the server that needs to be connected. Same as the beginning of the HTTP protocol, the URL of the WebSocket protocol starts with ws://, and the secure WebSocket protocol starts with wss://. The second line to the fifth line is the processing function of the WebSocket object registration message. The WebSocket object supports four messages onopen, onmessage, onclose and onerror. With these four events, we can easily control WebSocket. When the Browser and WebSocketServer are successfully connected, the onopen message will be triggered; if the connection fails, the sending or receiving of data fails, or there is an error in processing the data, the browser will trigger the onerror message; when the Browser receives the data sent by the WebSocketServer, it will trigger the onmessage message , The parameter evt contains the data transmitted by the Server; when the browser receives the connection close request sent by the WebSocketServer, it will trigger the onclose message. We can see that all operations are triggered by asynchronous callbacks, so that the UI will not be blocked, and faster response time and better user experience can be obtained.

5. WebSocket case analysis

Below we use a real customer case to analyze the advantages and specific development and implementation of WebSocket (to protect customer privacy, the customer name is omitted in the following description, and the code related to business details will not be repeated in the text).

5.1 Case introduction

The customer is a mobile device manufacturer. The mobile device is equipped with Android/IOS operating system. The devices are divided into two categories (hereinafter referred to as A and B). A device is in a mobile state at any time, and a device B is a device A For management and control equipment, customers need to see the geographic location information and status information of the A equipment in the B equipment at any time. For example, when a Class A device is online, when it is offline, a Class B device needs to be notified immediately, and when a Class A device reports, a Class B device also needs to obtain the geographic location information of the reported Class A device in real time. In order to reduce the difficulty of cross-platform and the workload of implementation, customers consider lightweight Web App to shield the differences between Android/IOS platforms. There are a large number of Class A devices, and Class A devices are in an irregular mobile state under working conditions. , And Class B equipment has very high requirements for real-time perception of changes in the state of Class A equipment (second level). According to the above requirements, the information of Class A/B devices is stored in the background database. The interaction of Class A/B devices involves frequent and highly concurrent requests from the Web client/server. If the traditional HTTP request-response mode is used, Class B The device's Web App needs to poll for services, which will inevitably bring a large load pressure on the server, and when the A device is not online or reporting events, the polling of the B device seriously wastes network resources.

5.2 Solution

In summary, the project uses WebSocket technology to realize real-time message notification and push. Whenever a Class A device/Class B device is online and successfully logged in, the WebSocket HTTP long connection is opened, and a new Class A device is online, location changes, offline, etc. Changes are sent through WebSocket in real-time messages, and the WebSocket Server processes the real-time messages from Class A devices and pushes them to subordinate Class B devices in real time. The WebSocket client uses jQuery Mobile (the development of jQuery Mobile mobile terminal will not be described in detail in this article, interested readers can refer to the introduction of jQuery Mobile), using the native WebSocket API to achieve interaction with the server. The server uses the customer’s existing application server Tomcat 7.0.33 version, uses Apache custom API to implement WebSocket Server, and generates a WebSocket HTTP long connection for an online type A device. Whenever a type A device is online, the location is updated , Offline and other events, the client sends a text message. After the server recognizes and processes it, it sends a real-time message to the class B device to which it belongs. After receiving the message, the class B device client recognizes the corresponding event of the class A device and completes the corresponding Class A equipment location refresh and other business operations. The interaction sequence diagram of Class A equipment, Class B equipment and background server involved is as follows. A/B type device WebSocket interaction diagram:
Insert picture description here
A/B type device WebSocket client is encapsulated in the JavaScript code of websocket.js, and packaged together with jQuery MobileApp as a mobile terminal apk/ipa installation package; WebSocket server implementation is mainly WebSocketDeviceServlet. java, WebSocketDeviceInbound.java, WebSocketDeviceInboundPool.java several classes. Below we introduce the specific code implementation one by one.

5.3 Code Implementation

In the following, we explain the main code implementation in this case, and readers can download the complete code list for detailed understanding. [WebSocketDeviceServlet class] After a class A device or a class B device initiates a WebSocket persistent connection, the server accepts the request is the WebSocketDeviceServlet class. Unlike traditional HttpServlet, the WebSocketDeviceServlet class implements the createWebSocketInbound method, similar to the accept method of SocketServer, and a newly produced WebSocketInbound instance Corresponding to the client's HTTP long connection, processing the interactive function with the client. WebSocketDeviceServlet server code example is as follows (WebSocketDeviceServlet.java code example):

public class WebSocketDeviceServlet extends org.apache.catalina.websocket.WebSocketServlet {
private static final long serialVersionUID = 1L;

 @Override
 protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) {
      WebSocketDeviceInbound newClientConn = new WebSocketDeviceInbound(request);
      WebSocketDeviceInboundPool.addMessageInbound(newClientConn);
      return newClientConn;
 }

}

Code explanation:

WebSocketServlet is the background monitoring process of the WebSocket protocol. Like traditional HTTP requests, WebSocketServlet is similar to the Servlet monitoring process in Spring/Struct, except that the client's ws prefix specifies its monitoring protocol as WebSocket.

WebSocketDeviceInboundPool implements the client-side WebSocket connection pool function similar to the JDBC database connection pool, and uniformly handles the message push of the WebSocket server to a single client/multiple clients (the same group of Class A devices). For details, see the WebSocketDeviceInboundPool code class explanation.

[WebSocketDeviceInboundl class] The WebSocketDeviceInbound class is the backend service class corresponding to the HTTP persistent connection established by the client after verifying login for each class A and class B device, similar to the Socket process after SocketServer accept in Socket programming, receiving the client in WebSocketInbound Send real-time location information and other messages, and send subordinate A device real-time location information and location analysis result data to the client (Class B device). The input stream and output stream are all customized by the WebSocket protocol. WsOutbound is responsible for outputting the results, and StreamInbound and WsInputStream are responsible for receiving data. WebSocketDeviceInbound.java class code example:

public class WebSocketDeviceInbound extends MessageInbound {
     private final HttpServletRequest request;
     private DeviceAccount connectedDevice;
 
     public DeviceAccount getConnectedDevice() {
          return connectedDevice;
     }
 
     public void setConnectedDevice(DeviceAccount connectedDevice) {
          this.connectedDevice = connectedDevice;
     }
 
     public HttpServletRequest getRequest() {
          return request;
     }
 
     public WebSocketDeviceInbound(HttpServletRequest request) {
          this.request = request;
          DeviceAccount connectedDa = (DeviceAccount)request.getSession(true).getAttribute("connectedDevice");
          if(connectedDa==null)
          {
               String deviceId = request.getParameter("id");
               DeviceAccountDao deviceDao = new DeviceAccountDao();
               connectedDa = deviceDao.getDaById(Integer.parseInt(deviceId));
          }
          this.setConnectedDevice(connectedDa);
     }
 
     @Override
     protected void onOpen(WsOutbound outbound) {
     }
 
     @Override
     protected void onClose(int status) {
          WebSocketDeviceInboundPool.removeMessageInbound(this);
     }
 
     @Override
     protected void onBinaryMessage(ByteBuffer message) throws IOException {
          throw new UnsupportedOperationException("Binary message not supported.");
     }
 
     @Override
     protected void onTextMessage(CharBuffer message) throws IOException {
          WebSocketDeviceInboundPool.processTextMessage(this, message.toString());
     }
 
     public void sendMessage(BaseEvent event)
     {
          String eventStr = JSON.toJSONString(event);
          try {
          this.getWsOutbound().writeTextMessage(CharBuffer.wrap(eventStr));
          //…以下代码省略
          } catch (IOException e) {
               e.printStackTrace();
          }
     }
}

Code explanation:

connectedDevice is the currently connected Class A/B client device class instance, which is used here as a member variable for subsequent processing interactions.

The sendMessage function sends data to the client, and uses the Websocket WsOutbound output stream to push the data to the client. The data format is unified as JSON.

The onTextMessage function triggers an event when the client sends a message to the server, and calls the processTextMessage of WebSocketDeviceInboundPool to uniformly process the login, update location, and offline messages of Class A devices.

The onClose function triggers the close event and removes the connection from the connection pool.

After the WebSocketDeviceInbound constructor establishes a connection for the client, the createWebSocketInbound function of WebSocketServlet is triggered to query the detailed data of the A/B device in the back-end database and instantiate connectedDevice as a member variable of WebSocketDeviceInbound. The WebSocketServlet class adds a new WebSocketInbound instance at this time In the custom WebSocketDeviceInboundPool connection pool, in order to uniformly process the business logic of the A/B device group member relationship and location distribution information calculation.

[WebSocketDeviceInboundPool class] WebSocketInboundPool class: Due to the need to process a large number of real-time messages from Class A and Class B devices, there will be a large number of HTTP persistent connections on the server side at the same time. For unified management and effective use of HTTP persistent connection resources, a simple HashMap is used in the project to achieve memory Connection pool mechanism, each time the device logs in to the newly created WebSocketInbound, it is put into the connection pool of the WebSocketInbound instance, and when the device logs out, the corresponding WebSocketInbound instance is removed from the connection pool. In addition, the WebSocketInboundPool class also assumes the role of the WebSocket client to process the message transmission between the Class A and Class B devices. When the client sends the login, logout and location update messages of the Class A device, the server WebSocketInboundPool calculates the location distribution information. And push the calculated result to the B-type equipment online at the same time. WebSocketDeviceInboundPool.java code example:

public class WebSocketDeviceInboundPool {
     private static final ArrayList<WebSocketDeviceInbound> connections = new ArrayList<WebSocketDeviceInbound>();
 
     public static void addMessageInbound(WebSocketDeviceInbound inbound){
          //添加连接
          DeviceAccount da = inbound.getConnectedDevice();
          System.out.println("新上线设备 : " + da.getDeviceNm());
          connections.add(inbound);
     }
 
     public static ArrayList<DeviceAccount> getOnlineDevices(){
          ArrayList<DeviceAccount> onlineDevices = new ArrayList<DeviceAccount>();
          for(WebSocketDeviceInbound webClient:connections)
          {
               onlineDevices.add(webClient.getConnectedDevice());
          }
          return onlineDevices;
     }
 
     public static WebSocketDeviceInbound getGroupBDevices(String group){
          WebSocketDeviceInbound retWebClient =null;
          for(WebSocketDeviceInbound webClient:connections)
          {
               if(webClient.getConnectedDevice().getDeviceGroup().equals(group)&&
                    webClient.getConnectedDevice().getType().equals("B")){
                    retWebClient = webClient;
               }
          }
          return retWebClient;
     }
 
     public static void removeMessageInbound(WebSocketDeviceInbound inbound){
          //移除连接
          System.out.println("设备离线 : " + inbound.getConnectedDevice());
          connections.remove(inbound);
     }
 
     public static void processTextMessage(WebSocketDeviceInbound inbound,String message){
          BaseEvent receiveEvent = (BaseEvent)JSON.parseObject(message.toString(),BaseEvent.class);
          DBEventHandleImpl dbEventHandle = new DBEventHandleImpl();
          dbEventHandle.setReceiveEvent(receiveEvent);
          dbEventHandle.HandleEvent();
          if(receiveEvent.getEventType()==EventConst.EVENT_MATCHMATIC_RESULT||
               receiveEvent.getEventType()==EventConst.EVENT_GROUP_DEVICES_RESULT||
               receiveEvent.getEventType()==EventConst.EVENT_A_REPAIRE){
               String clientDeviceGroup = ((ArrayList<DeviceAccount>)
               receiveEvent.getEventObjs()).get(0).getDeviceGroup();
               WebSocketDeviceInbound bClient = getGroupBDevices(clientDeviceGroup);
          if(bClient!=null){
               sendMessageToSingleClient(bClient,dbEventHandle.getReceiveEvent());
          }
     }
     }
     }
 
     public static void sendMessageToAllDevices(BaseEvent event){
          try {
               for (WebSocketDeviceInbound webClient : connections) {
                    webClient.sendMessage(event);
               }
          } catch (Exception e) {
               e.printStackTrace();
          }
     }
 
     public static void sendMessageToSingleClient(WebSocketDeviceInbound webClient,BaseEvent event){
          try {
                    webClient.sendMessage(event);
          }
          catch (Exception e) {
                e.printStackTrace();
     }
}
}

Code explanation:

The addMessageInbound function adds a connection established by the client to the connection pool.

The getOnlineDevices function gets all connected A/B devices.

The removeMessageInbound function realizes the offline exit of the class A device or the class B device (the server receives the client closing the WebSocket connection event and triggers the onClose method in WebSocketInbound), and deletes the connection instance of the connected device client from the connection pool.

processTextMessage completes processing of client messages. The message processing mechanism is used here, including decoding client messages, constructing Event events based on the messages, and multithreading through EventHandle. After processing, it returns to the client and can push messages to the group B devices. You can also push messages to the client that sent the message.

The sendMessageToAllDevices function realizes sending data to all online A/B device clients. The sendMessageToSingleClient function realizes sending data to a certain A/B device client.

[Websocket.js client code] The client code websocket.js, the client uses the WebSocket API defined by standard HTML5 to ensure support for IE9+, Chrome, FireFox and other browsers, and combines the jQueryJS library API to process JSON data and send. Client-side WebSocket.js script example:

var websocket=window.WebSocket || window.MozWebSocket;
var isConnected = false;
 
function doOpen(){
     isConnected = true;
     if(deviceType=='B'){
          mapArea='mapB';
     doLoginB(mapArea);
      }
      else{
           mapArea='mapA';
           doLoginA(mapArea);
      }
}
 
function doClose(){
     showDiagMsg("infoField","已经断开连接", "infoDialog");
     isConnected = false;
}
 
function doError() {
     showDiagMsg("infoField","连接异常!", "infoDialog");
     isConnected = false;
}
 
function doMessage(message){
var event = $.parseJSON(message.data);
doReciveEvent(event);
}
 
function doSend(message) {
     if (websocket != null) {
          websocket.send(JSON.stringify(message));
     } else {
          showDiagMsg("infoField","您已经掉线,无法与服务器通信!", "infoDialog");
     }
}
 
//初始话 WebSocket
function initWebSocket(wcUrl) {
     if (window.WebSocket) {
          websocket = new WebSocket(encodeURI(wcUrl));
          websocket.onopen = doOpen;
          websocket.onerror = doError;
          websocket.onclose = doClose;
          websocket.onmessage = doMessage;
     }
     else{
          showDiagMsg("infoField","您的设备不支持 webSocket!", "infoDialog");
     }
};
 
function doReciveEvent(event){
     //设备不存在,客户端断开连接
     if(event.eventType==101){
          showDiagMsg("infoField","设备不存在或设备号密码错!", "infoDialog");
          websocket.close();
     }
     //返回组设备及计算目标位置信息,更新地图
     else if(event.eventType==104||event.eventType==103){
          clearGMapOverlays(mapB);
           $.each(event.eventObjs,function(idx,item){
           var deviceNm = item.deviceNm;
           //google api
          // var deviceLocale = new google.maps.LatLng(item.lag,item.lat);
          //baidu api
           var deviceLocale = new BMap.Point(item.lng,item.lat);
           var newMarker;
           if(item.status=='target'){
                newMarker = addMarkToMap(mapB,deviceLocale,deviceNm,true);
                //…以下代码省略
           }
           else{
                newMarker = addMarkToMap(mapB,deviceLocale,deviceNm);
           }
           markArray.push(newMarker);
      });
      showDiagMsg("infoField","有新报修设备或设备离线, 地图已更新!", "infoDialog");
     }
}

Code explanation:

The doOpen callback function handles opening the WebSocket. After the Type A device or Type B device is connected to the WebSocket server, it will initialize the map and display the default location, and then send the device login message to the server.

The doReciveEvent function handles closing the WebSocket, and when the Class A/B device is offline (exiting the application on the mobile terminal), the server closes the HTTP persistent connection, and the client WebSocket object executes the onclose callback handle.

initWebSocket initializes WebSocket, connects to the WebSocket server, and sets the processing callback handle. If the browser version is too low and does not support HTML5, it will prompt the client that the device does not support WebSocket.

The doSend function processes the client to send messages to the server. Note that the message is a JSON OBJ object, and the string is formatted through the JSON standard API.

The doMessage function processes the message returned by the WebSocket server. The message returned in the background is a JSON string, which is formatted as JSON Object through jQuery's parseJSON API so that when the client processes the doReciveEvent function, the client receives the specific processing of the message returned by the server. A lot of business logic will not be repeated here.

6. Conclusion

This article introduces the origin of HTML5 WebSocket, the operating mechanism and the implementation of the client and server APIs, focusing on the detailed steps of the server (based on Tomcat7) and client (based on the browser’s native HTML5 API) implementation; and described through actual customer cases How the client uses HTTP persistent connection to realize real-time communication and message push function with the server under the WebSocket architecture, readers can have a deeper understanding of the technical principles and development methods of the WebSocket framework by reading the implementation of the sample code in this article.

In addition, some knowledge points about the development of c++ Linux background server are shared: Linux, Nginx, MySQL, Redis, P2P, K8S, Docker, TCP/IP, coroutine, DPDK, webrtc, audio and video, etc. Scan and pay attention!

Insert picture description here

Guess you like

Origin blog.csdn.net/lingshengxueyuan/article/details/107382030