前后端分离集成demo(后端)
首先是依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
1:编写配置类。把服务交给容器管理
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
2:编写服务信息
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/webSocket/{token}")
@Slf4j
@Component
public class WebSocket {
private static int onlineCount = 0;
private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
private Session session;
private String token;
@OnOpen
public void onOpen(@PathParam("token") String token, Session session) {
this.token = token;
this.session = session;
WebSocket.onlineCount++;
clients.put(token, this);
}
@OnClose
public void onClose() {
clients.remove(token);
WebSocket.onlineCount--;
}
@OnMessage
public void onMessage(String message) {}
@OnError
public void onError(Session session, Throwable throwable) {
log.error("WebSocket发生错误:" + throwable.getMessage());
}
public void sendMessage(String message) {
// 向所有连接websocket的客户端发送消息
// 可以修改为对某个客户端发消息
for (WebSocket item : clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
}
3:websocket的引入
4:这样后端就可以直接调用方法发送信息给websocket了
webSocket.sendMessage("");
前后端不分离项目demo
pom文件依赖
<!--引入springboot 的版本-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath />
</parent>
<!--设置编码格式-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--前端的模板视图thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!--json数据包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
后端实现如上一样就行
前端页面,
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script th:src="@{/jquery-2.0.3.min.js}" type="text/javascript"></script>
</head>
<body>
<input id="CreateSocket" type="button" value="创建WebSocKet" />
<input id="Message" type="text" value=""/>
<input id="Send" type="button" value="发送" />
<input id="Close" type="button" value="关闭WebSocket" />
</body>
<script type="text/javascript">
/**
* 创建 WebSocKet 的方法
*/
function createWebSocket(urlValue){
if("WebSocket" in window){
return new WebSocket(urlValue);
}
if ("MozWebSocket" in window){
return new MozWebSocket(urlValue);
}
console.error("浏览器不支持 WebSocKet");
}
/**
* 1, 创建WebSocket
* 2, WebScoket 的地址为ws协议
*/
var token = "knmlknalksndanslkmndflskamdsa";
var webSocket = null;
var urlValue = "ws://127.0.0.1:8000/webSocket/"+token;
$('#CreateSocket').on('click', function(){
//console.error("浏览器不支持 WebSocKet");
webSocket = createWebSocket(urlValue);
// 服务器返回数据时执行
webSocket.onmessage = function(msg){
console.log("浏览器接收到消息:" + msg.data);
}
// 请求关闭时执行
webSocket.onclose = function(){
console.log(arguments);
}
});
$('#Send').on('click', function(){
var message = $('#Message').val().trim();
if(message == ""){
console.error("发送的内容不能为空!");
return;
}
if(webSocket == null){
console.error("未创建 WebSocket 请求!");
return;
}
// 向服务器发送请求的方法
webSocket.send(message);
$('#Message').val("");
});
</script>
</html>
整体结构如下
注意:
有可能出现的问题:
1:在本地测试或者域名或ip访问的时候是没有任何问题的,可是部署到服务器上通过代理的时候访问出现了异常(主要是nginx 的反向代理),异常信息如下
访问地址 + Error during WebSocket handshake: Unexpected response code: 200
问题解决途径:官网查阅
通过nginx官网介绍可以得知服务会打印一条数据信息,然后去监听端口(这里是8010),然后等待连接,当接收了连接的请求,就会回显这些信息,然后把数据信息返回给客户。而要nginx去实现这个请求,我们就需要在nginx配置这一系列的配置。。。。
而我根据以上配置的意思进行了配置后,问题成功解决。
2:nginx进行反向代理的时候,可能会出现1分钟无操作就会断开连接的情况,这个是因为默认的无操作1min就会自动断开,
解决方案有两种,一种是前端定时发送一个心跳包,相当于重新刷新1min 的计时时间,另外一种就是nginx中配置超时时间即可,我这里配置的是一小时
别忘记刷新nginx