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 ...
随机推荐
- CSP2019题解
CSP2019题解 格雷码 按照生成的规则模拟一下即可. 代码 括号树 看到括号匹配首先想到用栈,然后又在树上就可以想到可追溯化栈. 令\(a_i=1\)表示\(i\)号节点上的括号为(,否则为), ...
- koa2+mysql+vue实现用户注册、登录、token验证
说明: node.js提供接口,vue展现页面,前后端分离,出于编辑器功能和编辑习惯,vue用HbuilderX,node.js用VScode.(PS:仅作为学习笔记,如有不当之处欢迎指出,在此先谢为 ...
- nodejs调用cmd命令
使用 child_process.exec 实现 child_process即子进程可以创建一个系统子进程并执行shell命令,在与系统层面的交互上非常有用 NodeJS子进程提供了与系统交互的重要接 ...
- rust下获取本机IP
又拾起了rust语言, 想写一点东西玩一玩, 但是发现连一个获取本机IP地址的库都没有, 还得挽起袖子自己撸. https://crates.io/crates/local_ipaddress 没有用 ...
- vs2019 更新之后无法用ctrl+d再设置回来..
工具-选项-环境-键盘
- jenkins+sonarqube进行代码质量检测
JavaNeverGiveUp教程篇 用jenkins+sonarqube去检查代码是非常方便的,它能检查出代码中可能存在的一些问题,比如io流未关闭.空指针异常.死循环.代码不规范等问题. 1. 搭 ...
- pandas的使用(6)离散化和合并
pandas的使用(6)离散化和合并
- HandlerInterceptorAdapter
handler,是指controller的@Controller注解下的整个方法名
- crushmap磁盘智能分组
目录 简介 配置crush class 1. 创建ssd class 2. 创建基于ssd的class rule 3. 创建基于ssd_rule规则的存储池 4. 测试基于ssd的池 简介 ceph从 ...
- Linux(centOS6.5)安装RabbitMQ
第一.下载erlang和rabbitmq-server的rpm: wget http://www.rabbitmq.com/releases/erlang/erlang-19.0.4-1.el7.c ...