1
0
Code Issues Pull Requests Packages Projects Releases Wiki Activity GitHub Gitee

[后端] webSocket demo跑通

This commit is contained in:
程序员小墨 2022-11-28 23:29:03 +08:00
parent a85d7bcfba
commit 432ba2b812
11 changed files with 382 additions and 2 deletions

View File

@ -413,10 +413,10 @@ cnpm install
```bash ```bash
npm run package npm run package
npm run make # npm run make
``` ```
`npm run make` 等于先执行 `npm run package`(即 *Import project into Forge*),再 *Create distributable*
@ -468,6 +468,12 @@ npm run serve
### Step3. 启动项目门禁端
编译并运行client-entrance-guard目录下electron项目即可
## 停止项目 ## 停止项目
### Step1. 停止各个微服务 ### Step1. 停止各个微服务

View File

@ -103,6 +103,12 @@
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
</dependency> </dependency>
<!-- WebSocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -0,0 +1,28 @@
package com.cxyxiaomo.epp.access.config;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
/**
* 开启WebSocket支持
*/
@Configuration
public class WebSocketConfig implements ServletContextInitializer {
/**
* 这个bean的注册,用于扫描带有@ServerEndpoint的注解成为websocket,如果你使用外置的tomcat就不需要该配置文件
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
}
}

View File

@ -0,0 +1,112 @@
package com.cxyxiaomo.epp.access.controller;
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.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer {
// 与某个客户端的连接会话需要通过它来给客户端发送数据
private Session session;
// session集合,存放对应的session
private static ConcurrentHashMap<Integer, Session> sessionPool = new ConcurrentHashMap<>();
// concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象
private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
/**
* 建立WebSocket连接
*
* @param session
* @param userId 用户ID
*/
@OnOpen
public void onOpen(Session session, @PathParam(value = "userId") Integer userId) {
log.info("WebSocket建立连接中,连接用户ID{}", userId);
try {
Session historySession = sessionPool.get(userId);
// historySession不为空,说明已经有人登陆账号,应该删除登陆的WebSocket对象
if (historySession != null) {
webSocketSet.remove(historySession);
historySession.close();
}
} catch (IOException e) {
log.error("重复登录异常,错误信息:" + e.getMessage(), e);
}
// 建立连接
this.session = session;
webSocketSet.add(this);
sessionPool.put(userId, session);
log.info("建立连接完成,当前在线人数为:{}", webSocketSet.size());
}
/**
* 发生错误
*
* @param throwable e
*/
@OnError
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
/**
* 连接关闭
*/
@OnClose
public void onClose() {
webSocketSet.remove(this);
log.info("连接断开,当前在线人数为:{}", webSocketSet.size());
}
/**
* 接收客户端消息
*
* @param message 接收的消息
*/
@OnMessage
public void onMessage(String message) {
log.info("收到客户端发来的消息:{}", message);
}
/**
* 推送消息到指定用户
*
* @param userId 用户ID
* @param message 发送的消息
*/
public static void sendMessageByUser(Integer userId, String message) {
log.info("用户ID" + userId + ",推送内容:" + message);
Session session = sessionPool.get(userId);
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error("推送消息到指定用户发生错误:" + e.getMessage(), e);
}
}
/**
* 群发消息
*
* @param message 发送的消息
*/
public static void sendAllMessage(String message) {
log.info("发送消息:{}", message);
for (WebSocketServer webSocket : webSocketSet) {
try {
webSocket.session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error("群发消息发生错误:" + e.getMessage(), e);
}
}
}
}

View File

@ -0,0 +1,19 @@
package com.cxyxiaomo.epp.access.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@Accessors(chain = true) // 链式写法
public class WebSocketData {
// 小程序: "miniprogram" 门禁: "guard"
private String type;
// 需要执行的动作
private String action;
// 传输的数据JSON字符串
private String json;
}

View File

@ -127,6 +127,13 @@
<version>4.10.0</version> <version>4.10.0</version>
</dependency> </dependency>
<!-- WebSocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.7.6</version>
</dependency>
<!-- Fastjson --> <!-- Fastjson -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>

View File

@ -118,6 +118,104 @@
} }
}, },
"response": [] "response": []
},
{
"name": "[微服务] 获取不限制的小程序码",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:8002/access/wechat/getUnlimitedQRCode?scene=t=1&page=pages/index/index",
"protocol": "http",
"host": [
"localhost"
],
"port": "8002",
"path": [
"access",
"wechat",
"getUnlimitedQRCode"
],
"query": [
{
"key": "envVersion",
"value": "develop",
"disabled": true
},
{
"key": "scene",
"value": "t=1"
},
{
"key": "page",
"value": "pages/index/index"
}
]
}
},
"response": []
},
{
"name": "[线上] 获取不限制的小程序码",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://epp.only4.work/access/wechat/getUnlimitedQRCode?scene=t=1&page=pages/index/index",
"protocol": "https",
"host": [
"epp",
"only4",
"work"
],
"path": [
"access",
"wechat",
"getUnlimitedQRCode"
],
"query": [
{
"key": "envVersion",
"value": "develop",
"disabled": true
},
{
"key": "scene",
"value": "t=1"
},
{
"key": "page",
"value": "pages/index/index"
}
]
}
},
"response": []
}
]
},
{
"name": "TestProvider",
"item": [
{
"name": "http://localhost:8011/hi/1",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:8011/hi/1",
"protocol": "http",
"host": [
"localhost"
],
"port": "8011",
"path": [
"hi",
"1"
]
}
},
"response": []
} }
] ]
} }

1
test-code/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

44
test-code/package-lock.json generated Normal file
View File

@ -0,0 +1,44 @@
{
"name": "test-code",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "test-code",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"ws": "^8.11.0"
}
},
"node_modules/ws": {
"version": "8.11.0",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
},
"dependencies": {
"ws": {
"version": "8.11.0",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"requires": {}
}
}
}

14
test-code/package.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "test-code",
"version": "1.0.0",
"description": "",
"main": "websocketTest.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"ws": "^8.11.0"
}
}

View File

@ -0,0 +1,45 @@
'use strict';
const WebSocket = require('ws');
const webSocketUrl = 'ws://localhost:8002/websocket/1';
global.ws = null; // WebSocket 实例对象
/**
* 启动完毕输出配置信息
*/
console.log("Start running ...", "process.env", process.env);
function createWebSocket() {
//申请一个WebSocket对象参数是服务端地址同http协议使用http://开头一样WebSocket协议的url使用ws://开头另外安全的WebSocket协议使用wss://开头
global.ws = new WebSocket(webSocketUrl);
// 当WebSocket创建成功时触发onopen事件
global.ws.onopen = function () {
console.log("webhook is open.");
}
// 当客户端收到服务端发送的关闭连接请求时触发onclose事件
global.ws.onclose = function (e) {
console.log("webhook is close.");
console.log("未知错误被关闭,等待 1s 尝试重新建立连接...");
setTimeout(function () {
createWebSocket();
}, 1000);
}
// 如果出现连接、处理、接收、发送数据失败的时候触发onerror事件
global.ws.onerror = function (e) {
console.log(e.error);
}
// 当客户端收到服务端发来的消息时触发onmessage事件参数e.data包含server传递过来的数据
global.ws.onmessage = function (e) {
var data = JSON.parse(e.data);
console.log(data);
}
}
// 创建连接
createWebSocket();