Web workers enable JS to have the ability of multi-threading, which can deliver complex and time-consuming operations to Worker threads for processing. WebSocket enables the Web end and the server to maintain an effective long connection, and the server to actively push data. Combining the two, the function of information flow notification of business system can be completely stripped out.
Architecture diagram
JS Worker
Worker DedicatedWorkerGlobalScope, the scope of the work in a dedicated in this scope, cannot directly manipulate the DOM node, cannot use the Windows default methods and properties of objects. But access to the network is no problem at all. Click here to see which objects and methods you can use
It can be clearly seen from the above figure that Worker implements a bridge between the left and right sides in the current architecture. The upper part connects the data in the socket and the lower part distributes the data in the socket. Here we first understand the function realization of Worker itself.
- The main thread passes the method to the Worker thread
postMessage
Send information to each other - The main thread passes an event with the Worker thread
onmessage
Receive messages that pass to each other - The use of third-party JS in Worker is introduced
importScripts([url,])
- Main thread call
worker.terminate()
The end of the thread - The Worker thread passes the call
this.close()
End its own thread
Create a new webworker.js file and write the following code in it
//author:herbert qq:464884492
onmessage = function (event) {
if (event.data.code) {
var code = event.data.code.toLowerCase();
switch (code) {
case "init":
var userId = event.data.loggedUserId;
var sessionId = event.data.sessionid;
if(! sessionId) {this.close();
return;
}
postMessage({ code: "codeone".msg: "Hello component 1" });
postMessage({ code: "codetwo".msg: "Hello component 2" });
break;
default:
break; }}}Copy the code
Note: Do not add var before onMessage, otherwise IE will not receive messages. Internet Explorer is such a frustrating browser
Create a new index.html page and write the following code in a script block to communicate with webworker.js
//author:herbert qq:464884492
var work = new Worker('webworker.js')
, textone = document.querySelector("#textone")
, textTwo = document.querySelector("#texttwo")
textAll = document.querySelector("#textAll");
work.onmessage = function (event) {
var data = event.data;
if(!!!!! data.code) {switch (data.code) {
case "close":
work.terminate();
case "codeone":
textone.value = textone.value + JSON.stringify(data) + "\r\n";
textAll.value = textAll.value + JSON.stringify(data) + "\r\n";
break;
case "codetwo":
textTwo.value = textTwo.value + JSON.stringify(data) + "\r\n";
textAll.value = textAll.value + JSON.stringify(data) + "\r\n";
break;
default:
textAll.value = textAll.value + JSON.stringify(data) + "\r\n"; }}}; work.postMessage({code: "init".loggedUserId: 'demo'.sessionid: 'demo'
});
Copy the code
JS WebSocket
WebSocket, like Http, is based on Tcp. The difference is that WebSocket implements full duplex communication between the server and the client. Before Websocket appeared, if you want to achieve a function of information push, the only solution to achieve through HTTP is rotation training, rotation training is divided into long and short, each has its drawbacks. Now that WebSocket comes along, everything is easy.
Next we set up a WebSocket connection
Method of root said the current scope, in the main thread is root = window, the root = DedicatedWorkerGlobalScope WebWorker thread
//author:herbert qq:464884492
var root = this,socket =null;
function connect(wsurl) {
if ('WebSocket' in root) {
socket = new WebSocket(wsurl);
} else if ('MozWebSocket' in root) {
socket = new MozWebSocket(wsurl);
} else {
alert("Your browser version is too old to receive system messages."); }}Copy the code
The wSURL format is WS :\\ or WSS :\\, which indicates SSL-encrypted transmission. Actual address such as: the ws: / / localhost: 8090 / demo/demowebsocket next, we need to handle events for the socket, is responsible for receiving the news of the server push
//author:herbert qq:464884492
function onOpen() {
postMessage({ code: "openConnect" });
}
function onClose() {
postMessage({ code: "closewsconnect" });
}
function onMessaage(event) {
postMessage(JSON.parse(event.data));
}
function onError(event) {
socket = null;
if (event.target.readyState == 3) {
// Reconnection
setTimeout(function () {
connect(event.target.url);
initMessageEvent();
}, 1000); }}function sendMessage(msg) {
if (socket == null) return;
socket.send(msg);
}
function initMessageEvent() {
socket.onopen = onOpen; // The socket connection was successfully processed
socket.onclose = onClose; // The socket connection is closed
socket.onmessage = onMessaage; The socket received a new message
socket.onerror = onError; //soket error handling event
}
Copy the code
JAVA WebSocket
Tomcat7x already implements the standard WebScoket interface, and you can implement a standard WebSocket Api in a project by writing a common entity bean configuration annotation. The development mainly uses some annotations
- @serverendpoint Sets the WebSocket connection address and URL parameters such as: @serverendpoint (value = “/ demowebSocket /{userId}/{sessionId}”), where {userId} and {sessionId} are
pathParam
This can be obtained in the onOpen function with the @pathParam function argument - @pathParam gets the annotation parameter corresponding to the URL address
- @onopen establishes connection annotations
- @onclose Closes the connection annotation
- @onMessage Receives message annotations
- @onError Error annotation
Annotated functions can choose any of the parameters they want, including Session, EndpointConfig, and @pathParam. The server Bean code is shown below
//author:herbert qq:464884492
@ServerEndpoint(value = "/demowebsocket/{userId}/{sessionId}")
public class DemoWebSokcet {
private static final Set<DemoWebSokcet> connections = new CopyOnWriteArraySet<DemoWebSokcet>();
private Session session;
public DemoWebSokcet(a) {}@OnOpen
public void openConnection(Session session, EndpointConfig conf,
@PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) {
this.session = session;
connections.add(this);
JSONObject jo = new JSONObject();
jo.put("code"."newuser");
jo.put("userid", userId);
jo.put("sessionid", sessionId);
jo.put("msg"."Server: new user");
sendMessage(jo);
// Test the code
JSONObject jo1 = new JSONObject();
jo1.put("code"."codeone");
jo1.put("userid", userId);
jo1.put("sessionid", sessionId);
jo1.put("msg"."Server: Component 1 Hello");
sendMessage(jo1);
JSONObject jo2 = new JSONObject();
jo2.put("code"."codetwo");
jo2.put("userid", userId);
jo2.put("sessionid", sessionId);
jo2.put("msg"."Server: Component 2 Hello");
sendMessage(jo2);
}
@OnClose
public void closeConnection(@PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) {
connections.remove(this);
JSONObject jo = new JSONObject();
jo.put("code"."connectionClose");
jo.put("userid", userId);
jo.put("sessionid", sessionId);
jo.put("msg"."Server: Connection closed");
sendMessage(jo);
}
// Process text messages
@OnMessage
public void handleTextMsg(Session session, String message,
@PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) {
System.out.println("userId=>" + userId + " sessionId=>" + sessionId);
// Forward client messages as is
sendMessage(JSONObject.parseObject(message));
}
// Process binary messages
@OnMessage
public void handleBinaryMsg(Session session, ByteBuffer msg,
@PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) {}// Handle pong messages
@OnMessage
public void handlePongMsg(Session session, PongMessage msg,
@PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) {
JSONObject jo = new JSONObject();
jo.put("code"."pong");
jo.put("userid", userId);
jo.put("sessionid", sessionId);
jo.put("msg", msg.getApplicationData().toString());
sendMessage(jo);
}
@OnError
public void onError(Throwable t, @PathParam("userId") String userId,
@PathParam("sessionId") String sessionId) throws Throwable {
JSONObject jo = new JSONObject();
jo.put("code"."servererror");
jo.put("userid", userId);
jo.put("sessionid", userId);
jo.put("msg", t.getMessage());
sendMessage(jo);
}
private static void sendMessage(JSONObject msg) {
for (DemoWebSokcet client : connections) {
try {
synchronized(client) { client.session.getBasicRemote() .sendText(msg.toJSONString()); }}catch (IOException e) {
JSONObject jo = new JSONObject();
jo.put("code"."servererror");
jo.put("userid",
client.session.getPathParameters().get("userid"));
jo.put("sessionid",
client.session.getPathParameters().get("sessionid"));
connections.remove(client);
try {
client.session.close();
} catch (IOException e1) {
}
jo.put("msg"."Server: abnormal message sending, connection closed"+ e.getMessage()); sendMessage(jo); }}}}Copy the code
Javax. websocket-API is introduced through POM in the process of test code writing. Error occurs during Websocket Handshake: Unexpected Response Code: 404 Connection error. Later, copy the jar of tomcat implementation in direct package tomcat/bin to the bin folder of WebApp to solve the problem.
The Demo preview
conclusion
It’s a long book, and it’s not easy to read here! WebWorker and WebSocket were also the first time I combined them. Feel now javascript function is really more and more rich. Demo address, there is a bit of sentiment, for the development of new knowledge points, first of all you have to learn how to use, secondly through reading the source code, and theoretical knowledge to let you use more smoothly, and even change it.
There are technical friends like to chat welcome to the group, if the TWO-DIMENSIONAL code failure can add my wechat reply front end