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服务的更多相关文章

  1. C# WebSocket 服务端示例代码 + HTML5客户端示例代码

    WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...

  2. 使用websocket-sharp来创建c#版本的websocket服务

    当前有一个需求,需要网页端调用扫描仪,javascript不具备调用能力,因此需要在机器上提供一个ws服务给前端网页调用扫描仪.而扫描仪有一个c#版本的API,因此需要寻找一个c#的websocket ...

  3. 小程序server-3-搭建WebSocket 服务

    小程序server-3-搭建WebSocket 服务: 1.安装 Node 模块 使用 ws 模块来在服务器上支持 WebSocket 协议,下面使用 NPM 来安装: cd /var/www/wxp ...

  4. 使用nodejs创建加入用户验证的websocket服务

    使用nodejs创建websocket服务是非常简单的(”ws”模块等),网上教程也很多.websocket服务默认没有连接验证,再加上它支持跨域连接,这样就存在“盗连”和并发攻击的风险. nodej ...

  5. DotnetBrowser入门教程-(3)启动与使用简单的WebSocket服务

    websocket是个很好的通信协议,基本可以贯穿支持html5的所有设备.dotnetbrowser内置了对websocket服务端与客户端的支持.请看例子: 1.新建桌面项目,基于.net 4.0 ...

  6. nodejs搭建简单的websocket服务端

    创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...

  7. WebSocket服务端

    http://blog.csdn.net/qq_20282263/article/details/54310737 C# 实现WebSocket服务端 原创 2017年01月10日 09:22:50 ...

  8. YxdIocp包含有支持大并发的TCP服务组件、HTTP服务组件、UDP服务组件、WebSocket服务组件

    Delphi Windows IOCP 通讯模型封装,基于DIOCP.YxdIocp包含有支持大并发的TCP服务组件.HTTP服务组件.UDP服务组件.WebSocket服务组件,和TCP.UDP等基 ...

  9. 用nodejs快速实现websocket服务端(带SSL证书生成)

    有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的 ...

  10. 听说江苏省没有webSocket服务硬件

    听说江苏省没有webSocket服务硬件 昨天项目上线,我门开发采用的webSocket做实时轮询,然后开发部老总怒怼"江苏省没有webSocket服务硬件,江苏省没有webSocket服务 ...

随机推荐

  1. [专题总结]Gridea快速免费搭建个人博客

    介绍 或许你很想把你所知道的问题写出来,或许你文思泉涌,想给大家分享.我相信,你一定能写好博客,只要坚持,就可以了. 或许大家会不理解,为什么不用大平台的博客呢?或许你稍微了解就会知道,现在的博客平台 ...

  2. vscode+eslint项目规范化,自动格式化配置(项目中用到的)

    项目如果没有格式化插件就会变得十分拥挤,并且因为个人的开发习惯不同,会导致多人配合的时候,某些人的格式不能与你的兼容 导致项目大面积冲突,这样一来统一的格式和开发规范就十分必要了. 1.下载使用vsc ...

  3. Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0.

    Scss/Sass 项目里使用 / 报错:Using / for division outside of calc() is deprecated and will be removed in Dar ...

  4. LeetCode算法训练 93.复原IP地址 78.子集 90.子集II

    欢迎关注个人公众号:爱喝可可牛奶 LeetCode算法训练 93.复原IP地址 78.子集 90.子集II LeetCode 93. 复原 IP 地址 分析 字符串全部由数字组成,ipv4每一段数字不 ...

  5. webgl 系列 —— 绘制一个点(版本2、版本3、版本4、版本5)

    绘制一个点 我们初步认识了 webgl,本篇主要围绕绘制一个点的示例,逐步实现下面功能: 点的位置从 js 传入着色器 点的大小由 js 传入着色器 通过鼠标点击绘点 通过鼠标点击绘点,并改变点的颜色 ...

  6. Android 之Map容器替换 SparseArray,ArrayMap,ArraySet

    高效程序有两个重要指标:速度,内存,移动app中内存比重要多一些,为此在速度相差不是很大的时候,优先考虑内存,container是一个重要部分,对此google对一些原java容器设计新的容器进行替换 ...

  7. 【狂神说】SpringMVC笔记

    1.回顾MVC ssm:mybatis+Spring+SpringMVC MVC三层架构 ssm框架:研究官方文档,锻炼自学能力,锻炼项目能力 SpringMVC+Vue+SpringBoot+Spr ...

  8. 新手必学matplotlib

    Getting started Installation quick-start Install using pip: pip install matplotlib Install using con ...

  9. 预处理指令详解(C语言

    一.预处理符号 预处理符号是C语言内置的符号,是可以直接使用的. 其中,若遵顼ANSI C,则__STDC__ 为1,否则未定义. 二.#define 1)定义标识符 define可以用来定义标识符, ...

  10. python日志logging配置

    python日志logging配置 为了方便ELK收集日志,将日志打印成json格式 开发过程中,使用json格式不方便排查问题 本文章使用python的logging模块,一步步增加配置,来说明每个 ...