springmvc 整合 netty-socketio
1 maven
<dependency>
<groupId>com.corundumstudio.socketio</groupId>
<artifactId>netty-socketio</artifactId>
<version>1.7.12</version>
</dependency> 2 为了使服务运行启动需要实现 ApplicationListener 重写里面的方法 onApplicationEvent
import com.corundumstudio.socketio.*;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.corundumstudio.socketio.listener.ExceptionListenerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service; @Service
public class SocketIoServer implements ApplicationListener<ContextRefreshedEvent> { private SocketIOServer server; @Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
//端口
int WSS_PORT=9001;
//服务器ip
String WSS_HOST="127.0.0.1"; if( server== null) {
Configuration config = new Configuration();
//服务器ip
config.setHostname(WSS_HOST);
config.setPort(WSS_PORT);
//该处进行身份验证h
config.setAuthorizationListener(new AuthorizationListener() {
@Override
public boolean isAuthorized(HandshakeData handshakeData) {
//http://localhost:8081?username=test&password=test
//例如果使用上面的链接进行connect,可以使用如下代码获取用户密码信息
//String username = data.getSingleUrlParam("username");
//String password = data.getSingleUrlParam("password");
return true;
}
});
config.setExceptionListener(new ExceptionListenerAdapter() {
@Override
public boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {
System.out.println("错误:\n" + e.getMessage());
ctx.close();
return true;
}
});
server = new SocketIOServer(config);
//添加链接事件监听
server.addConnectListener(new ConnectListener() {
@Override
public void onConnect(SocketIOClient client) {
String clientId = client.getHandshakeData().getSingleUrlParam("clientid");
SocketIOClient si = ChatServerPool.getSocketIOClientByClientID(clientId); //这个客户端有没有连接过
// 如果没有连接信息、则新建会话信息
if (si == null) {
//在线数加1
//将会话信息更新保存至集合中
ChatServerPool.addUser(clientId, client); }
//在线数减1
System.out.println("socket 连接、sessionId:" + client.getSessionId() + "、clientId:" +
clientId+",当前人数:"+ChatServerPool.onLineCount.get() );
}
});
//添加销毁链接事件监听
server.addDisconnectListener(new DisconnectListener() {
@Override
public void onDisconnect(SocketIOClient client) {
String clientId = client.getHandshakeData().getSingleUrlParam("clientid");
ChatServerPool.removeUser(clientId);
//在线数减1
System.out.println("socket 断开连接、sessionId:" + client.getSessionId() + "、clientId:" +
clientId+",当前人数:"+ChatServerPool.onLineCount.get() ); }
});
//添加发送消息事件监听
server.addEventListener("message_event", MessageInfo.class, new DataListener<MessageInfo>() {
@Override
public void onData(SocketIOClient client, MessageInfo data, AckRequest ackSender) throws Exception {
MessageInfo sendData = new MessageInfo();
sendData.setSourceClientId(data.getSourceClientId());
sendData.setTargetClientId(data.getTargetClientId());
sendData.setMsg(data.getMsg());
// 向当前会话发送信息
ChatServerPool.sendMessageToUserBySocketClient(client,"message_event",sendData.getMsg().toString());
// 向目标会话发送信息
ChatServerPool.sendMessageToUser(data.getTargetClientId(),"message_event",sendData.getMsg().toString());
} });
//需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
server.start();
System.out.println("start****************************server***"+WSS_PORT+"***********************end"); }
} }
3
ChatServerPool.java
import com.corundumstudio.socketio.SocketIOClient;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger; public class ChatServerPool { //会话集合
private static final ConcurrentSkipListMap<String, SocketIOClient> webSocketMap = new ConcurrentSkipListMap<>();
//静态变量,用来记录当前在线连接数。(原子类、线程安全)
public static AtomicInteger onLineCount = new AtomicInteger(); /**
* SocketIOClient
*/
public static SocketIOClient getSocketIOClientByClientID(String clientID){
SocketIOClient sc = webSocketMap.get(clientID);
return sc;
} /**
* 向连接池中添加连接
*/
public static void addUser(String clientID, SocketIOClient conn){
if(conn !=null) {
webSocketMap.put(clientID, conn); //添加连接
onLineCount.incrementAndGet();
}
} /**
* 获取所有的在线用户
* @return
*/
public static Collection<String> getOnlineUser(){
Set<String> setUsers = webSocketMap.keySet();
return setUsers;
} /**
* 移除连接池中的连接
*/
public static boolean removeUser(String clientID){
if(webSocketMap.containsKey(clientID)){
webSocketMap.remove(clientID); //移除连接
return true;
}else{
return false;
}
} /**
* 向特定的用户发送数据
*/
public static void sendMessageToUser(String clientId,String event,String msg){
if(webSocketMap.containsKey(clientId) && !"".equals(msg)){
webSocketMap.get(clientId).sendEvent(event, msg);
}
}
/**
* 向特定的用户发送数据
*/
public static void sendMessageToUserBySocketClient(SocketIOClient conn,String event,String msg){
if(conn !=null && !"".equals(msg)){
conn.sendEvent(event, msg);
}
}
/**
* 向所有的用户发送消息
* @param message
*/
public static void sendMessageAll(String event,String message){
Collection<SocketIOClient> cs = webSocketMap.values();
synchronized (cs) {
if(event !=null && !"".equals(event)){
for (SocketIOClient conn : cs) {
if(conn != null){
conn.sendEvent(event,message);
}
}
}else{
for (SocketIOClient conn : cs) {
if(conn != null){
conn.sendEvent(message);
}
}
} }
} }
4 MessageInfo.java
public class MessageInfo {
private String targetClientId ;
private String sourceClientId;
private Object msg ; public String getTargetClientId() {
return targetClientId;
} public void setTargetClientId(String targetClientId) {
this.targetClientId = targetClientId;
} public String getSourceClientId() {
return sourceClientId;
} public void setSourceClientId(String sourceClientId) {
this.sourceClientId = sourceClientId;
} public Object getMsg() {
return msg;
} public void setMsg(Object msg) {
this.msg = msg;
}
}
4 script
<script>
var clientId='sys',targetId='sys001' ;
var socket = io.connect('http://localhost:9001?clientid=sys'); socket.on('connect', function () {
showMsg(':<span class="connect-msg">成功连接到服务器!</span>');
});
socket.on('message_event', function (data) {
showMsg('<br /><span class="username-msg">' + data.sourceClientId + ':</span> ' + data.msg);
});
socket.on('disconnect', function () {
showMsg(':<span class="disconnect-msg">服务已断开!</span>');
});
function sendDisconnect() {
socket.disconnect();
}
function sendMessage() {
var message = $('#msg').val();
$('#msg').val('');
var jsonObject = {
sourceClientId: clientId,
targetClientId: targetId,
msg: message
};
socket.emit('message_event', jsonObject);
}
function showMsg(message) {
var currentTime = "<span class='time'>2019-01-01</span>";
var element = $("<div>" + currentTime + "" + message + "</div>");
$('#console').append(element);
} </script>
springmvc 整合 netty-socketio的更多相关文章
- (转)Dubbo与Zookeeper、SpringMVC整合和使用
原文地址: https://my.oschina.net/zhengweishan/blog/693163 Dubbo与Zookeeper.SpringMVC整合和使用 osc码云托管地址:http: ...
- SSM整合(三):Spring4与Mybatis3与SpringMVC整合
源码下载 SSMDemo 上一节整合了Mybatis3与Spring4,接下来整合SpringMVC! 说明:整合SpringMVC必须是在web项目中,所以前期,新建的就是web项目! 本节全部采用 ...
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- springmvc整合fastjson
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 【转】Dubbo_与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
原文链接:http://blog.csdn.net/congcong68/article/details/41113239 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服 ...
- 160906、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- Springmvc整合tiles框架简单入门示例(maven)
Springmvc整合tiles框架简单入门示例(maven) 本教程基于Springmvc,spring mvc和maven怎么弄就不具体说了,这边就只简单说tiles框架的整合. 先贴上源码(免积 ...
- SpringMVC整合Tiles框架
SpringMVC整合Tiles框架 Tiles组件 tiles-iconfig.xml Tiles是一个JSP布局框架. Tiles框架为创建Web页面提供了一种模板机制,它能将网页的布局和内容分离 ...
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)转
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- SpringMVC整合Shiro——(3)
SpringMVC整合Shiro,Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能. 第一步:配置web.xml <!-- 配置Shiro过滤器,先让Shiro ...
随机推荐
- 【day05】css
一.盒模型(BoxModel) 1.width 宽度 2.height 高度 说明: 块元素和有宽高属性的标记(img,input) 能设置宽度和高度,而行元素不能设置宽高 3 ...
- 来吧!一文彻底搞定Vue组件!
作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子 ...
- android 完全退出实现
实现方法是在application中定义一个集合存储所有的Activity对象,在Activity创建时添加进集合中,在程序退出时,finish掉所有的Activity即可. 步骤如下: 1.自定义A ...
- 微信小程序如何进行本地调试
1.下载并使用微信开发者工具 2.将项目导入工具 3.在项目中修改请求http地址 4.在工具上点击“测试号”,跳转到测试号管理界面设置request合法域名. 注意这里输入的测试域名要和上一步相同. ...
- uwsgi异常服务器内存cpu爆满
记录线上服务器通过linux性能检测工具glances检测到 cpu.内存爆满,且是uwsgi进程占用,对于服务器内核,以及uwsgi配置优化 参考文章 https://blog.csdn.net/o ...
- java web开发入门十二(idea创建maven SSM项目需要解决的问题)基于intellig idea(2019-11-09 11:23)
一.spring mvc action返回string带双引号问题 解决方法: 在springmvc.xml中添加字符串解析器 <!-- 注册string和json解析适配器 --> &l ...
- windows上MongoDB远程访问配置
今天用另一台机器上的MongoDB,但是使用本地连接时,没问题 换成IP地址时,出现 解决的方法,修改配置文件 systemLog: destination: file path: d:/Mongod ...
- Azure DevOps Server (TFS) 代码库Repo管理培训
Repo是分布式代码库Git中的一个专用词,用于存储和管理开发团队中特定的源代码. 使用Git,可以协调整个团队的代码更改. 即使您只是一个开发人员,版本控制也可以帮助您在修复错误和开发新功能时保持井 ...
- [转载]DevExpress GridControl 使用方法技巧 总结 收录整理
最近开始用DevExpress组件,发现很好的经验总结博客,在这里转载分享 原作者:https://www.cnblogs.com/wordgao/p/4517011.html 一.如何解决单击记录整 ...
- 关于预装操作系统的ThinkPad的分区建议
Think的个人电脑产品大部分预装有正版操作系统,当前新产品出厂时默认都是一个大分区“C”和一个恢复分区“Q”,很多用户都会要求客服人员提供分区服务,在这里我简单说一下关于分区的几点注意事项望各位参考 ...