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服务 ...
随机推荐
- 题解 P2602 [ZJOI2010] 数字计数
虽然说是数位 dp 入门题但是还是不是很会(悲 看了题解才做出来,中途因为各种 SB 问题调了很长时间(悲 聪明的你一定能看出来这是数位 dp,因此令 \(i\) 为当前填的位数,\(limit\) ...
- LeetCode-593 有效的正方形
来源:力扣(LeetCode)链接:https://leetcode.cn/problems/valid-square 题目描述 给定2D空间中四个点的坐标 p1, p2, p3 和 p4,如果这四个 ...
- go 语言 for循环的一个坑
1.案例1 package main import "fmt" type Card struct { id int } func main() { list := make([]* ...
- nginx反向代理hyperf
location / { #反向代理到 本地9501端口 proxy_pass http://127.0.0.1:9501; proxy_redirect off; p ...
- 微信电脑版 v3.9.2.12 绿色便携版
修改历史: 2023.03.01:自改官方 3.9.2.12 最新正式版本2023.01.31:自改官方 3.9.0.28 最新正式版本2023.01.11:自改官方 3.9.0.21 最新正式版本- ...
- pytest框架增加log打印(包括pytest的执行结果、自定义的log信息)
前言: 之前同事在跑脚本的时候报错了,发现没法把需要的log信息打印出来,我这边定位问题比较麻烦,所以增加了log的打印.这个问题之前已经处理过了,本来以为是小问题,结果今天又要用到这个小技巧的时候居 ...
- 【面试题】JS 中这些继承方式你知道吗?
携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 29 天,点击查看活动详情 问题描述 继承 是基于面向对象的,使用 继承 可以让我们更好的复用以前开发的代码,缩短开发的周期.提 ...
- Iperf参数详解
IperfIperf是一个网络性能测试工具,可以测试TCP和UDP最大带宽,具有多种参数和UDP特性,可以根据需要调整,报告带宽,延迟,数据包丢失 通用参数-b(bandwidth):指定UDP模式使 ...
- Document.createEvent与new Event区别
Document.createEvent 写法: const e = document.createEvent('HTMLEvents'); e.initEvent('click', true, tr ...
- c-->static关键字的使用
static关键字的使用 static:静态 未使用static 在下列代码中变量a是有生命周期的,调用完后就会被销毁 所以for循环每次调用test函数打印的结果都是2 #include <s ...