WebSocket
First, the production of WebSocket
Users want Web pages to interact, the technology used to solve this problem is JavaScript, and now there are many JavaScript frameworks available on the web that can create rich single-page web--with minimal javascript Ajax Technology (Asynchronous JavaScript and XML).
With Ajax, the Web application in the browser can communicate with the server-side components without changing the browser page or refreshing. This communication process does not require the user to know, and it can be used to send new data to the server or to obtain new data from the server.
However, the browser can only get new data from the server zone, but the browser does not know when the data is used, only the server knows when the new data is sent to the browser, and the browser does not know.
Workaround 1, frequent polling
Frequently polling servers to obtain new data at a fixed frequency, usually once per second, the browser sends AJAX requests to the server to query for new data. If the browser has new data to send to the server, the data is added to the polling request and sent together to the browser (but a large number of requests are wasted).
Workaround 2, long polling
The server responds to the browser only when it sends data (if the browser has new data to send before the server responds, the browser must create a new parallel request, or terminate the current request; TCP and HTTP specify the connection timeout; HTTP has a forced connection limit).
Workaround 3, chunked encoding
The server can respond to requests without declaring the content length. In the response, the beginning of each block is a number that represents the block length, a series of optional characters that represent the block extension, and a CRLF (carriage return line) sequence. Then the block contains the data and another CRLF. The browser will create a long-life connection to the downstream endpoint, and the server will use that connection to send updates to the browser in chunks.
Workaround 4,applet and Adobe Flash
Create a normal TCP socket connection to the server, and when the browser has new data to send to the server, it will call the Java or Flash method by the JavaScript DOM function exposed by the browser plug-in, and then the method bar data is forwarded to the server.
Workaround 5,websocket
The WebSocket connection will first use a non-normal HTTP request to access a url,websocket that is a persistent full-duplex communication protocol in a specific mode. After the handshake is complete, the text and binary messages can be sent in two directions at the same time without having to close and reconnect.
Advantages of WebSocket:
- The connection ports are in the (WS) and 433 (WSS), so they are not blocked by firewalls.
- Using an HTTP handshake, you can naturally integrate into your Web browser and HTTP server.
- Use ping and pong to keep websocket active.
- Both the server and the client can know when a message is started and its contents arrive.
- WebSocket sends a special shutdown message when the connection is closed.
- Can support cross-region connections.
Second, WebSocket API
WebSocket is not just a browser and server communication, two applications written in any framework that support WebSocket can create websocket connections for communication.
WebSocket's Java API is contained in Javax.websocket and specifies a set of classes and interfaces that contain all the common features.
Client API
The client API is built on the Containerprovider class and the Websocketcontainer, Remoteendpoint, and session interfaces.
Websocketcontainer provides access to all WebSocket client features, while the Containerprovider class listens to the static Getwebsocketcontainer method used to obtain the implementation of the underlying WebSocket client.
Websocketcontainer provides 4 overloaded Connecttoserver methods that will accept a URI that connects to the remote terminal and initiates the handshake.
- Any type of Pojo marked with @clientendpoint
- The class< of any type of Pojo marked with @clientendpoint;? >
- An instance of the endpoint class or a class<? Extends Endpoint>.
When the handshake is complete, the Connecttoserver method returns a session.
Where WebSocket's endpoint has 3 methods, OnOpen, OnClose, and onerror, they will be called when these times occur.
The @clientendpoint class labels the methods of @onopen, @onClose, and @onerror.
- @OnOpen method can have: an optional session parameter, an optional endpointconfig parameter.
- @OnClose method can have: an optional session parameter, an optional Closereason parameter.
- @OnError method can have: an optional session parameter, an optional throwable parameter.
- @OnMessage method can have: an optional session parameter, a combination of other parameters.
This is a websocket to create a multiplayer game server terminal code:
Public classtictactoeserver{Private StaticMap<long, game> games =NewHashtable<>(); Private StaticObjectmapper mapper =NewObjectmapper (); @OnOpen Public voidOnOpen (Session session, @PathParam ("GameId")LonggameId, @PathParam ("Username") String username) {Try{tictactoegame Tictactoegame=Tictactoegame.getactivegame (gameId); if(Tictactoegame! =NULL) {Session.close (NewClosereason (CloseReason.CloseCodes.UNEXPECTED_CONDITION,"This game has already started." )); } List<String> actions = Session.getrequestparametermap (). Get ("Action"); if(Actions! =NULL&& actions.size () = = 1) {String action= Actions.get (0); if("Start". Equalsignorecase (Action)) {Game Game=NewGame (); Game.gameid=gameId; Game.player1=session; TicTacToeServer.games.put (gameId, game); } Else if("Join". Equalsignorecase (Action)) {Game Game=TicTacToeServer.games.get (gameId); Game.player2=session; Game.tictactoegame=tictactoegame.startgame (gameId, username); This. Sendjsonmessage (Game.player1, game,Newgamestartedmessage (game.tictactoegame)); This. Sendjsonmessage (Game.player2, game,Newgamestartedmessage (game.tictactoegame)); } } } Catch(IOException e) {e.printstacktrace (); Try{session.close (NewClosereason (CloseReason.CloseCodes.UNEXPECTED_CONDITION, e.tostring ())); } Catch(IOException ignore) {}}} @OnMessage Public voidOnMessage (Session session, String message, @PathParam ("GameId")LonggameId) {Game Game=TicTacToeServer.games.get (gameId); BooleanIsPlayer1 = Session = =Game.player1; Try{Move Move= TicTacToeServer.mapper.readValue (message, Move.class); Game.ticTacToeGame.move (IsPlayer1?TicTacToeGame.Player.PLAYER1:TicTacToeGame.Player.PLAYER2, Move.getro W (), Move.getcolumn ()); This. sendjsonmessage (IsPlayer1?Game.player2:game.player1), game,Newopponentmademovemessage (move)); if(Game.ticTacToeGame.isOver ()) {if(Game.ticTacToeGame.isDraw ()) { This. Sendjsonmessage (Game.player1, game,Newgameisdrawmessage ()); This. Sendjsonmessage (Game.player2, game,Newgameisdrawmessage ()); } Else { BooleanWasPlayer1 = Game.ticTacToeGame.getWinner () = =TicTacToeGame.Player.PLAYER1; This. Sendjsonmessage (Game.player1, game,Newgameovermessage (wasPlayer1)); This. Sendjsonmessage (Game.player2, game,NewGameovermessage (!wasPlayer1)); } game.player1.close (); Game.player2.close (); } } Catch(IOException e) { This. HandleException (E, game); }} @OnClose Public voidOnClose (Session session, @PathParam ("GameId")LonggameId) {Game Game=TicTacToeServer.games.get (gameId); if(Game = =NULL) return; BooleanIsPlayer1 = Session = =Game.player1; if(Game.tictactoegame = =NULL) {tictactoegame.removequeuedgame (Game.gameid); } Else if(!Game.ticTacToeGame.isOver ()) {Game.ticTacToeGame.forfeit (IsPlayer1?TicTacToeGame.Player.PLAYER1:TicTacToeGame.Player.PLAYER2); Session opponent= (isPlayer1?)game.player2:game.player1); This. Sendjsonmessage (opponent, game,Newgameforfeitedmessage ()); Try{opponent.close (); } Catch(IOException e) {e.printstacktrace (); } } }
Server API
The server API relies on the full client API, which adds only a handful of classes and interfaces, Servercontainer integrates Websocketcontainer, and calls Servletcontext.getattribute in the servlet environment ( "Javax.websocket.server.ServerCOntainer") to obtain an Servercontainer instance, in a stand-alone application, The Servercontainer instance needs to be obtained according to the instructions implemented by the specific websocket.
However, you can actually use the @serverendpoint label server Terminal class, WebSocket implementation can scan the class annotations, and automatically select and register the server terminal, the container in each receive WebSocket connection, create an instance of the corresponding terminal, after the connection is closed after destroying the instance.
In the use of @serverendpoint, it is necessary to develop at least the required value attribute target that the terminal can make the URL corresponding to the application like:
@ServerEndpoint ("/tictactoe/{gameid}/{username}")
If the application is deployed to the address: Http://www.example.org/app, then the server terminal responds with the address: Ws://www.example.org/app/tictactoe/1/andre, ETC., All @onopen, @OnClose, @OnError, and @onmessage methods in the server terminal can then be labeled with an optional additional parameter using only @pathparam ("{gameid}/{username}"). And its content is the value of the parameter change (1/andre).
The time processing method in the server terminal will work just like the time-processing method in the client, the difference exists only in the handshake phase, and there is no difference between the server and the client.
Java Web advanced Programming (IV)