1.说明
关于websocket的介绍,有许多的文章都讲的很详细也很好,这里就不再赘述。这里提供websocket的java代码简单实现,包括js的客户端和后台java的服务端,后端使用TomcatWebsocket和SpringWebSocket两种方式,实现tcp连接和通信,以供大家学习参考。
2.环境准备
后端使用SpringBoot加Maven构建项目,前端直接使用html加js实现。请先准备一个能够跑起来的SpringBoot后端项目。
添加websocket的maven依赖(pom.xml):
<!-- webSocket的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.7.12</version>
</dependency>
3.TomcatWebsocket后端代码
3.1 websocket配置类
将这个配置类加入项目中。
/**
* 配置后会自动注册所有的 @ServerEndpoint,一定不要忘记这个配置类
* @author 广大网友
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3.2 websocket服务端代码
@ServerEndpoint注解添加服务端路径 path ,客户端在建立连tcp接时就使用:var ws = new WebSocket(“ws://你的后台项目地址/path”); 建立连接。需要携带参数时:var ws = new WebSocket(“ws://你的后台项目地址/path?accessToken=某某”) 建立连接。
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
/**
* TomcatWebSocket服务端
*
* @author 别人家的孩子e
*/
@Component
@ServerEndpoint("/test/tomcatWebsocket")
public class WebSocketEndPoint {
/**
* 注意,多个会话会公用这一个num对象
*/
private static Integer num = 1;
/**
* tcp连接建立时触发
*/
@OnOpen
public void onOpen(Session session) throws IOException {
System.out.println("会话:" + session.getId() + "的tcp连接已建立。");
//获得路径中携带的参数,通常为认证token
List<String> accessToken = session.getRequestParameterMap().get("accessToken");
//注意判路径中是否有携带参数
if (accessToken != null && accessToken.size() > 0){
String token = accessToken.get(0);
System.out.println("会话人token:" + token);
}else {
System.out.println("会话人无访问token!!!");
}
}
/**
* 接收到消息时触发
*/
@OnMessage
public String onMessage(Session session, String message) {
//这里假定在访问url中都携带accessToken
List<String> accessToken = session.getRequestParameterMap().get("accessToken");
String token = accessToken.get(0);
System.out.println("服务端接收的消息:" + message + "---消息属于会话:" + session.getId() + "。token:" + token);
return "服务端收到第" + num++ + "条消息";
}
/**
* 遇到错误时触发
*/
@OnError
public void onError(Throwable t) {
System.out.println("webSocket遇到问题:");
t.printStackTrace();
}
/**
* tcp连接关闭时触发
*/
@OnClose
public void onClose(Session session, CloseReason reason) {
//这里假定在访问url中都携带accessToken
List<String> accessToken = session.getRequestParameterMap().get("accessToken");
String token = accessToken.get(0);
System.out.println("会话:" + session.getId() + "的连接已关闭。token:" + token);
num = 1;
}
}
4.SpringWebSocket后端代码
实现方式和TomcatWebSocket略有区别,而效果相同,前端代码改一下访问地址就ok。
4.1 添加拦截器
SpringWebsocket需要使用拦截器获取请求路径中的参数。
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 因为 WebSocketSession 无法获得 ws 地址上的请求参数,所以只好通过该拦截器,获得 accessToken 请求参数,设置到 attributes 中。
*
* 也可以 implements HandshakeInterceptor
* @author 别人家的孩子e
*/
@Component
public class WebSocketShakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
// 从请求路径中获得 accessToken
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request;
HttpServletRequest servletRequest = serverRequest.getServletRequest();
attributes.put("accessToken", servletRequest.getParameter("accessToken"));
}
// 调用父方法,继续执行逻辑
return super.beforeHandshake(request, response, wsHandler, attributes);
}
}
4.2 添加消息处理器
对应TomcatWebSocket的服务端点(WebSocketEndPoint)。但是访问路径在4.3中配置。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
/**
* 处理连接和消息
*
* @author 别人家的孩子e
*/
@Component
public class DemoWebSocketHandler extends TextWebSocketHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 对应 open 事件
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.info("[afterConnectionEstablished][session({}) 接入]", session);
// 解析 accessToken
String accessToken = (String) session.getAttributes().get("accessToken");
System.out.println("连接建立,token:" + accessToken);
}
/**
* 对应 message 事件
*/
@Override
public void handleTextMessage(WebSocketSession session, TextMessage textMessage) throws Exception {
logger.info("[handleMessage][session({}) 接收到一条消息({})]", session, textMessage);
System.out.println("textMessage:" + textMessage.toString());
System.out.println("textMessage.getPayload():" + textMessage.getPayload());
session.sendMessage(new TextMessage("服务端收到,over。"));
}
/**
* 对应 close 事件
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
logger.info("[afterConnectionClosed][session({}) 连接关闭。关闭原因是({})}]", session, status);
System.out.println(session.getAttributes().get("accessToken").toString() + "的连接已关闭。");
}
/**
* 对应 error 事件
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
logger.info("[handleTransportError][session({}) 发生异常]", session, exception);
System.out.println("连接异常!!");
}
}
4.3 添加配置
将前面定义的拦截器和消息处理器添加到配置中。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
* 、@EnableWebSocket :开启 springwebsocket
*
* @author 别人家的孩子e
*/
@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {
/**
* addHandler:配置处理器
* addInterceptors:配置拦截器
* setAllowedOrigins: 设置跨域
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry
.addHandler(new DemoWebSocketHandler(), "/test/springWebsocket")
.addInterceptors(new WebSocketShakeInterceptor())
.setAllowedOrigins("*");
}
}
5.前端代码
直接c走。文章来源:https://www.toymoban.com/news/detail-790772.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="referrer" content="no-referrer">
<title>websocket案例</title>
<style>
body{
background-image: url("https://wallpaperm.cmcm.com/7aee1626bc5e2d89129aa61f6b6f2582.jpg");
background-color: lightyellow;
background-size: cover;
}
#sendMessage{
height: 30px;
color:brown;
}
#closeWebSocket{
height: 30px;
color: red;
}
#show{
background-color: antiquewhite;
width: 500px;
margin: auto;
text-align: left;
opacity: 0.7;
}
</style>
</head>
<body>
<div style="width: 100%;text-align: center;color:black;background-color: antiquewhite;opacity: 0.7;">
<h1>websocket测试用例</h1>
<h2 style="color: red;">记得给我点个赞!!!</h2>
<button id="sendMessage">点击发送消息</button>
<button id="closeWebSocket">点击关闭tcp连接</button>
<div id="show">
<h4 id="onopen">onopen:</h4>
<h4 id="onmessage">onmessage:</h4>
<h4 id="onerror">onerror:</h4>
<h4 id="onclose">onclose:</h4>
</div>
</div>
<script>
//和websocket服务端建立tcp连接,刷新页面触发
var ws = new WebSocket("ws://127.0.0.1:8080/test/tomcatWebsocket?accessToken=秀儿"); //连接tomcatWebsocket
//var ws = new WebSocket("ws://127.0.0.1:8080/test/springWebsocket?accessToken=秀儿"); //连接springWebsocket
/* websocket客户端部分API如下 */
// 1.连接建立时触发
ws.onopen = function(){
//send方法用于向服务器发送消息
ws.send('这是客户端在tcp连接建立后发送的消息');
let onopen = document.getElementById('onopen');
onopen.innerText = 'onopen: ' + "webSocket客户端已和服务端创建tcp连接。";
};
// 2.接收到webSocket服务端消息就触发
ws.onmessage = function(evt){
let onmessage = document.getElementById('onmessage');
onmessage.innerText = 'onmessage: ' + evt.data;
};
//3.出现异常时触发
ws.onerror = function(evt){
let onerror = document.getElementById('onerror');
onerror.innerText = 'onerror: ' + "webSocket发生异常!";
};
// 4.连接关闭时触发
ws.onclose = function(evt){
let onclose = document.getElementById('onclose');
onclose.innerText = 'onclose: ' + "webSocket的tcp连接已关闭。";
};
//点击发送消息按钮
let sendMessageButton = document.getElementById('sendMessage');
sendMessageButton.onclick = function () {
ws.send('客户端发送了消息到服务器端');
}
//点击关闭tcp连接按钮
let closeButton = document.getElementById('closeWebSocket');
closeButton.onclick = function(){
//关闭websocket的tcp连接
ws.close();
}
</script>
</body>
</html>
后端项目跑起来就能实现tcp通信了。文章来源地址https://www.toymoban.com/news/detail-790772.html
到了这里,关于websocket简单的java代码示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!