WebSocket服务
package com.sxsoft.admin.Component; import com.alibaba.fastjson.JSON;
import io.netty.handler.codec.http.HttpHeaders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.yeauty.annotation.*;
import org.yeauty.pojo.Session;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet; /**
* @program: sxsoft_bidlater_guarantee
* @ClassName WebSocket
* @description: 进行群推送以及单点推送 部署时docker要配置端口(docker-compose.yml),并且服务器要允许端口开放外网。websocket端口与主程序端口要区分开来
* @create: 2023-01-05 09:13
* @Version 1.0
**/
//调用如(http是ws开头,https是wss开头): ws://localhost:8816/ws/bhbl/123
@Slf4j
@Component
@ServerEndpoint(path = "/ws/bhbl/{userId}", port = "${sxsoft.data.app-config.netty-websocket.port}")
public class NettyWebSocket { //无参构造
// public NettyWebSocket() {
// System.out.println("通过这里可以看到 每次请求过来都会创建");
// } //region 内部私有方法
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session; //连接用户ID
private String userId; //虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
//NettyWebSocket是当前类名
private static CopyOnWriteArraySet<NettyWebSocket> webSockets =new CopyOnWriteArraySet<>();
// concurrent包的线程安全Set,用来存在线连接用户信息
private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>(); //加载静态文件
// static {
// String roomStr = FileToJsonUtils.readData("/config/room.json");
// JSONArray rooms = JSON.parseArray(roomStr);
// for (Object object : rooms) {
// JSONObject room = (JSONObject) object;
// roomMap.put(room.getString("code"), room);
// }
// } @BeforeHandshake
public void handshake(Session session, HttpHeaders headers,@PathVariable String arg, @PathVariable String group) {
session.setSubprotocols("stomp");
} /**
* 建立连接
* @param session
* @param headers
*/
@OnOpen
public void onOpen(Session session, HttpHeaders headers, @PathVariable String userId) {
//判断是否有此群组,没有则关闭连接
try {
this.session = session;
this.userId = userId;
webSockets.add(this);
sessionPool.put(userId, session);
log.info("【websocket消息】有新的连接,总数为:{},userid:{}",webSockets.size(),userId);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 关闭连接
* @param session
*/
@OnClose
public void onClose(Session session){
try {
webSockets.remove(this);
sessionPool.remove(this.userId);
log.info("【websocket消息】连接断开,总数为:"+webSockets.size());
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 错误回调
* @param session
* @param throwable
*/
@OnError
public void onError(Session session, Throwable throwable) {
log.error("用户错误,原因:"+throwable.getMessage());
throwable.printStackTrace();
} /**
* 接收消息
* @param message
*/
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】收到客户端消息:"+message);
} /**
* 绑定数据流
* @param session
* @param bytes
*/
@OnBinary
public void onBinary(Session session, byte[] bytes) {
session.sendBinary(bytes);
} /**
* 绑定事件
* @param session
* @param evt
*/
@OnEvent
public void onEvent(Session session, Object evt) {
// if (evt instanceof IdleStateEvent) {
// IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
// switch (idleStateEvent.state()) {
// case READER_IDLE:
// System.out.println("read idle");
// break;
// case WRITER_IDLE:
// System.out.println("write idle");
// break;
// case ALL_IDLE:
// System.out.println("all idle");
// break;
// default:
// break;
// }
// }
}
//endregion //region 消息发送 /**
* 广播消息
* @param message
*/
public static void sendAllMessage(String message) {
log.info("【websocket消息】广播消息:"+message);
try {
for(NettyWebSocket webSocket : webSockets) {
if(webSocket.session.isOpen()) {
webSocket.session.sendText(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 单点消息
* @param userId
* @param message
*/
public static void sendOneMessage(String userId, String message) {
try {
log.info("【websocket消息】 单点消息:"+message);
Session session = sessionPool.get(userId);
log.info("【websocket消息】 单点消息,当前在线投标人session:{}", JSON.toJSONString(session));
if (session != null && session.isOpen()) {
session.sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 单点消息(多人)
* @param userIds
* @param message
*/
public static void sendMoreMessage(String[] userIds, String message) {
try { log.info("【websocket消息】 单点消息(多人),userids={},message={}", JSON.toJSONString(userIds),message);
for(String userId:userIds) {
Session session = sessionPool.get(userId);
log.info("【websocket消息】 单点消息(多人),当前在线审核人session:{}", JSON.toJSONString(session));
if (session != null && session.isOpen()) {
session.sendText(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//endregion }
<!--netty-websocket-spring-boot-->
<dependency>
<groupId>org.yeauty</groupId>
<artifactId>netty-websocket-spring-boot-starter</artifactId>
<version>0.9.5</version>
</dependency>
<!-- netty工具类 -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
WebSocket服务的更多相关文章
- C# WebSocket 服务端示例代码 + HTML5客户端示例代码
WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- 使用websocket-sharp来创建c#版本的websocket服务
当前有一个需求,需要网页端调用扫描仪,javascript不具备调用能力,因此需要在机器上提供一个ws服务给前端网页调用扫描仪.而扫描仪有一个c#版本的API,因此需要寻找一个c#的websocket ...
- 小程序server-3-搭建WebSocket 服务
小程序server-3-搭建WebSocket 服务: 1.安装 Node 模块 使用 ws 模块来在服务器上支持 WebSocket 协议,下面使用 NPM 来安装: cd /var/www/wxp ...
- 使用nodejs创建加入用户验证的websocket服务
使用nodejs创建websocket服务是非常简单的(”ws”模块等),网上教程也很多.websocket服务默认没有连接验证,再加上它支持跨域连接,这样就存在“盗连”和并发攻击的风险. nodej ...
- DotnetBrowser入门教程-(3)启动与使用简单的WebSocket服务
websocket是个很好的通信协议,基本可以贯穿支持html5的所有设备.dotnetbrowser内置了对websocket服务端与客户端的支持.请看例子: 1.新建桌面项目,基于.net 4.0 ...
- nodejs搭建简单的websocket服务端
创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...
- WebSocket服务端
http://blog.csdn.net/qq_20282263/article/details/54310737 C# 实现WebSocket服务端 原创 2017年01月10日 09:22:50 ...
- YxdIocp包含有支持大并发的TCP服务组件、HTTP服务组件、UDP服务组件、WebSocket服务组件
Delphi Windows IOCP 通讯模型封装,基于DIOCP.YxdIocp包含有支持大并发的TCP服务组件.HTTP服务组件.UDP服务组件.WebSocket服务组件,和TCP.UDP等基 ...
- 用nodejs快速实现websocket服务端(带SSL证书生成)
有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的 ...
- 听说江苏省没有webSocket服务硬件
听说江苏省没有webSocket服务硬件 昨天项目上线,我门开发采用的webSocket做实时轮询,然后开发部老总怒怼"江苏省没有webSocket服务硬件,江苏省没有webSocket服务 ...
随机推荐
- 提取show config命令结果
import re import os # 从命令收集日志文件中,提取show config命令结果. file_list = os.listdir(os.getcwd()) dirname = os ...
- vue路由中pdfjs插件使用及找不到 viewer.html解决
官方下载: https://mozilla.github.io/pdf.js/getting_started/#download 同目录下pdfjs-2.12.313-dist.zip为官方下载包 此 ...
- Postgresql实现不同用跨模式访问
1.修改参数 2.创建两个用户 创建a1 create user a1 connection limit-1 password '123456'; alter user a1 SUPERUSER; g ...
- 跟女朋友介绍十个常用的 Python 内置函数,她夸了我一整天
内置函数是什么 了解内置函数之前,先来了解一下什么是函数 将使用频繁的代码段进行封装,并给它起一个名字,当我们使用的时候只需要知道名字就行 函数就是一段封装好的.可以重复使用的代码,函数使得我们的程序 ...
- win10bug可导致系统崩溃
1.使用浏览器访问访问路径:\\.\globalroot\device\condrv\kernelconnect会立刻导致系统崩溃.会影响Windows10 1709及以上版本 2.使用以下代码保存成 ...
- Mysql数据库基础第六章:变量、存储过程与函数
Mysql数据库基础系列 软件下载地址 提取码:7v7u 数据下载地址 提取码:e6p9 mysql数据库基础第一章:(一)数据库基本概念 mysql数据库基础第一章:(二)mysql环境搭建 mys ...
- JAVA-GUI创作学校管理系统
1.对于学校的管理系统,我们先做一个简单的一个需求分析,我们需要做学生信息管理,教师信息管理,课程的信息管理.我们要根据自己的需求进行数据库的编写. 简单的添加了几个 2.然后我们通过eclipse+ ...
- Unable to preventDefault inside passive event listener invocation.
问题:如图所示 Unable to preventDefault inside passive event listener invocation. 解决方案: 应用 CSS 属性 touch-act ...
- Python语言课程实验报告 (第三周)
Python语言基础实验(第三周) 一.实验目的和要求 1.了解流程控制语句的结构与类型: 2.学习语句的使用: 3.掌握流程控制语句的实际应用. 二.实验环境 软件版本:Python 3.10 64 ...
- Software--C#--grammer_Delegate--Event
2018-05-01 10:49:47 委托是一种类型,而事件是一个类或结构的成员,如同字段,属性.必须在类或结构中声明. 引申 - Observe 观察者模式 Publish/Subscribe ...