Tomcat7 以后开始支持 websocket 协议
Spring4 以后开始支持 WebSocket
Netty3 以后支持开发 WebSocket
<!-- Spring boot WebSocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* Created by Administrator on 2018/11/28 0028.
* @ServerEndpoint :标识此类为 Tomcat 的 websocket 服务终端,/websocket/yy.action 是客户端连接请求的路径
* @Component :将本类交由 spring IOC 容器管理
*/
@ServerEndpoint(value = "/websocket/yy.action")
@Component
public class ServerEnpoint {
private static Logger logger = LoggerFactory.getLogger(ServerEnpoint.class);
/**
* 用 Set 来 存储 客户端 连接
*/
private static Set<Session> sessionSet = new HashSet<>();
/**
* 连接成功后自动触发
*
* @param session
*/
@OnOpen
public void afterConnectionEstablished(Session session) {
/**
* session 表示一个连接会话,整个连接会话过程中它都是固定的,每个不同的连接 session 不同
* String queryString = session.getQueryString();//获取请求地址中的查询字符串
* Map<String, List<String>> parameterMap = session.getRequestParameterMap();//获取请求地址中参数
* Map<String, String> stringMap = session.getPathParameters();
* URI uri = session.getRequestURI();
*/
sessionSet.add(session);
logger.info("新客户端加入,session id=" + session.getId() + ",当前客户端格个数为:" + sessionSet.size());
/**
* session.getBasicRemote().sendText(textMessage);同步发送
* session.getAsyncRemote().sendText(textMessage);异步发送
*/
session.getAsyncRemote().sendText("我是服务器,你连接成功!");
}
/**
* 连接断开后自动触发,连接断开后,应该清楚掉 session 集合中的值
*
* @param session
*/
@OnClose
public void afterConnectionClosed(Session session) {
sessionSet.remove(session);
logger.info("客户端断开,session id=" + session.getId() + ",当前客户端格个数为:" + sessionSet.size());
}
/**
* 收到客户端消息后自动触发
*
* @param session
* @param textMessage :客户端传来的文本消息
*/
@OnMessage
public void handleMessage(Session session, String textMessage) {
try {
logger.info("接收到客户端信息,session id=" + session.getId() + ":" + textMessage);
/**
* 原样回复文本消息
* getBasicRemote:同步发送
* session.getAsyncRemote().sendText(textMessage);异步发送
* */
session.getBasicRemote().sendText(textMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 消息传输错误后
*
* @param session
* @param throwable
*/
@OnError
public void handleTransportError(Session session, Throwable throwable) {
System.out.println("shake client And server handleTransportError,session.getId()=" + session.getId() + " -- " + throwable.getMessage());
logger.error("与客户端 session id=" + session.getId() + " 通信错误...");
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* Created by Administrator on 2018/11/28 0028.
*/
@Configuration
public class WebSocketConfig {
/**
* 创建 ServerEndpointExporter 组件,交由 spring IOC 容器管理,
* 它会自动扫描注册应用中所有的 @ServerEndpoint
*
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
/**
* web socket 绑定
*/
var ws = null;
function webSocketBind() {
/**主流浏览器现在都支持 H5 d的 webSocket 通信,但建议还是要判断*/
if ("WebSocket" in window) {
/**创建 web socket 实例
* 如果连接失败,浏览器控制台报错,连接失败
* 前缀 ws:// 必须正确,yyServer 是应用名称,websocket/yy.action 是后台访问路径
* 192.168.1.20:websocket 服务器地址
* */
ws = new WebSocket("ws://192.168.1.20/yyServer/websocket/yy.action");
/**onopen:服务器连接成功后,自动触发*/
ws.onopen = function () {
/** Web Socket 已连接上,使用 send() 方法发送数据*/
//ws.send("connect success...");
console.log("服务器连接成功,并发送数据到后台...");
};
/**服务器发送数据后,自动触发此方法,客户端进行获取数据,使用 evt.data 获取数据*/
ws.onmessage = function (evt) {
var received_msg = evt.data;
console.log("接收到服务器数据:" + received_msg);
showClientMessage(received_msg);
};
/**客户端与服务器数据传输错误时触发*/
ws.onerror = function (evt) {
console.log("客户端 与 服务器 数据传输错误...");
};
/**web Socket 连接关闭时触发*/
ws.onclose = function () {
console.log("web scoket 连接关闭...");
};
} else {
alert("您的浏览器不支持 WebSocket!");
}
}
/**
* 显示服务器发送的消息
* @param message
*/
let showServerMessage = function (message) {
if (message != undefined && message.trim() != "") {
/**
* 往服务器发送消息
*/
ws.send(message.trim());
/**
* scrollHeight:div 区域内文档的高度,只能 DOM 操作,JQuery 没有提供相应的方法
* @type {string}
*/
let messageShow = "<div class='messageLine server'><div class='messageContent serverCon'>" + message + "</div><span>:我</span>";
$(".centerTop").append(messageShow + "<br>");
$(".messageArea").val("");
let scrollHeight = $(".centerTop")[].scrollHeight;
$(".centerTop").scrollTop(scrollHeight - $(".centerTop").height());
}
};
/**
* 显示客户端的消息
* @param message
*/
let showClientMessage = function (message) {
if (message != undefined && message.trim() != "") {
/**
* scrollHeight:div 区域内文档的高度,只能 DOM 操作,JQuery 没有提供相应的方法
* @type {string}
*/
let messageShow = "<div class='messageLine client'><span>服务器:</span><div class='messageContent clientCon'>" + message + "</div>";
$(".centerTop").append(messageShow + "<br>");
$(".messageArea").val("");
let scrollHeight = $(".centerTop")[].scrollHeight;
$(".centerTop").scrollTop(scrollHeight - $(".centerTop").height());
}
};
$(function () {
/**初始化后清空消息发送区域*/
$(".messageArea").val("");
/**
* 为 消息 发送按钮绑定事件
*/
$(".sendButton").click(function () {
let message = $(".messageArea").val();
showServerMessage(message);
});
/**
* 绑定键盘敲击事件 —— 用于按 回车键 发送消息
*/
$(window).keydown(function (event) {
if (event.keyCode === 13) {
let message = $(".messageArea").val();
showServerMessage(message);
}
});
/**
* 绑定 webSocket,连接 服务器
*/
webSocketBind();
});