WebSocket使用场景介绍
实现两个系统之间的数据交互,A系统中的echarts图需要在B系统的固定位置进行展示,用到了WebSocket,A系统点击发送按钮,会把echarts图的数据传输给B系统,B系统获取到数据,进行echarts展示 这里为什么没有使用socket:原因是:传统的socket,是一个长连接,客户端连接服务端,如果客户端和服务端都没有发送数据,就会造成资源浪费。 使用了WebSocket,WebSocket他是一种长连接,通过一次请求来初始化连接,然后所有的请求和响应都是通过这个TCP连接进行通讯,它是一种基于事件驱动,异步的消息机制。原理和TCP一样,只需要一个握手动作,就可以形成一条快速通道。
什么是WebSocket?
WebSocket是一种在单个TCP(传输控制协议:是面向连接的、可靠的、基于字节流之间的传输层通信协议)连接上进行全双工通信的协议。
全双工和单工的区别: 全双工:可在信号载波的两个方向同时传输 单工:一方固定为发送端,一方固定为接收端,信息只能从一条传输线朝一个方向传播
WebSocket通信的客户端是浏览器,客户端操作的API是HTML5新增的API,使用这些API可以让客户端(浏览器)和服务端(服务器)进行全双工通讯。
WebSocket图解:
客户端代码
<!DOCTYPE HTML>
<html>
<head>
<title>My WebSocket</title>
</head>
<body>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>
<script type="text/javascript">
var websocket = null;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/websocketss");
} else {
alert('Not support websocket')
}
websocket.onopen = function(event) {
}
websocket.onerror = function() {
setMessageInnerHTML("error");
};
websocket.onmessage = function(event) {
setMessageInnerHTML("前端展示" + event.data);
}
websocket.onclose = function() {
setMessageInnerHTML("close");
}
window.onbeforeunload = function() {
websocket.close();
}
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
function closeWebSocket() {
websocket.close();
}
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>
客户端代码图解
服务端代码
首先是WebSocket配置类:
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
package com.hjjc.common.utils;
import com.alibaba.fastjson.JSON;
import com.hjjc.information.domain.MyMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@ServerEndpoint(value ="/websocketss")
@Component
public class MyWebSocket {
private static AtomicInteger onlineCount = new AtomicInteger(0);
private static Map<String, Session> clients = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
onlineCount.incrementAndGet();
clients.put(session.getId(), session);
}
@OnClose
public void onClose(Session session) {
onlineCount.decrementAndGet();
clients.remove(session.getId());
}
@OnMessage
public void onMessage(String message, Session session) {
try {
Model myMessage = JSON.parseObject(message, Model.class);
if (myMessage != null) {
for (Map.Entry<String, Session> entry:clients.entrySet( )){
if (entry.getValue() != null) {
this.sendMessage(message, entry.getValue());
}
}
}
} catch (Exception e) {
}
}
private void sendMessage(String message, Session toSession) {
try {
toSession.getBasicRemote().sendText(message);
} catch (Exception e) {
}
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
}
package com.hjjc.information.domain;
import lombok.Data;
@Data
public class MyMessage {
private String userId;
private String message;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
服务端发送给客户端数据实例:
@RequestMapping("/send")
public void send10(String sendData){
Map maps = (Map) JSON.parse(sendData);
maps.put("type","pie");
String sendData10F = JSONObject.toJSONString(maps);
MyWebSocket.onMessage(sendData10F,null);
}
客户端这边接收到的数据是json类型,使用到echarts上需要先转为map类型,然后获取map中的数据,进行填充echarts
websocket.onmessage = function(event) {
objToStrMap(JSON.parse(event.data));
}
function objToStrMap(obj){
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k,obj[k]);
}
let type = strMap.get("type");
|