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 ...
随机推荐
- MySQL实战45讲学习笔记:第一讲
一.MySQL逻架构图 二.连接器工作原理刨析 1.连接器工作原理图 2.原理图说明 1.连接命令 mysql -h$ip -P$port -u$user -p 2.查询链接状态 3.长连接端连接 1 ...
- 来吧!一文彻底搞定Vue组件!
作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子 ...
- [LeetCode] 737. Sentence Similarity II 句子相似度之二
Given two sentences words1, words2 (each represented as an array of strings), and a list of similar ...
- 实战django(二)--登录实现记住我
上节初步实现了登录和注册模块,这节我们进一步实现“记住我”功能. 大体功能分为以下模块: 1.在登录时如果勾选记住我,那么就将用户username存进cookie中,跳转到index页面: 2.此时, ...
- C/C++深度优先搜索(递归树模拟)
//C++深度优先搜索(递归树模拟) #define _CRT_SECURE_NO_WARNINGS #include <iostream> #define MAX_N 1000 usin ...
- Axios构造函数学习笔记
Axios 构造函数 lib/core/axios.js ... var intercaptorManager = require(./IntercaptorManger); var dispatch ...
- Balking模式
Balking模式讲的是如果现在不合适执行这个操作,或者没必要执行这个操作,就停止处理,直接返回 自动保存功能的实现逻辑一般都是隔一定时间自动执行存盘操作,存盘操作的前提是文件做过修改,如果文件没有执 ...
- HTML--元素居中各种处理方法
1.水平居中 对于行内元素可以使用: .center-children { text-align: center; } 对于块元素,你可以设置其左右外边距为:auto;同时你还应该设置该元素的宽度,不 ...
- SublimeText3安装Markdown插件
由于Webstrom对md文件的预览效果并不理想(与实际网页编译效果差别较大),所以我又改用Sublime进行本地编辑,下面介绍一下怎么搭建环境. 插件安装 整套环境我们就需要两个插件:Markdow ...
- struts2拦截器的实现机制
前言 最近老大让每周写一篇技术性的博客,想想也没啥写,就想着随便拿个以前的项目去研究研究五大框架的底层代码.本人水平有限,有不对的地方还望大家勿喷,指正! 开始之前先了解下strtus2的工作流程: ...