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 ...
随机推荐
- fft.ntt,生成函数,各种数和各种反演
前置知识: 一,导数 倒数其实就是函数的斜率函数 设D[f(x)]表示f(x)的导数,则满足 $$1,D[f(x)]=\lim\limits_{\delta x->\infty}\frac{f( ...
- RAID及磁盘配额
RAID的对比: 版本 特点 磁盘个数 可用空间 故障磁盘数 应用环境 RAID0 读写速度快,数据容易丢失 两个 全部 一块 测试,临时性 RAID1 读写速度慢,数据可靠 至少两个,可以2的倍数 ...
- 【2019.7.15 NOIP模拟赛 T2】与非树(nand)(树形DP)
树形\(DP\) 实际上,这道题应该不是很难. 我们设\(f_{x,i,j}\)表示在以\(x\)为根的子树内,原本应输出\(i\),结果输出了\(j\)的情况数. 转移时,为了方便,我们先考虑与,再 ...
- MySQL实战45讲学习笔记:第十一讲
一.如何在邮箱这样的字段上建立合理的索引 现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题. 假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的 ...
- [LeetCode] 393. UTF-8 Validation 编码验证
A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: For 1-byte char ...
- oracle--表空间故障
一,错误问题描述 ERROR: ORA: cannot identify - see DBWR trace file ORA: data : '/u01/oracle/TEST/oratmp01/te ...
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext之解决办法
错误产生背景:将之前用Eclipse写的Blog项目迁移到Idea上面.Ecilpse项目一直是没有问题的. 错误原因分析:原因是项目依赖中引入的jpa,另外也与Idea比较智能也有关系 解决办法: ...
- IDCode校验算法
运行地址: https://c.runoob.com/compile/10 算法源码 public class HelloWorld { public static void main(String ...
- Security实现登录安全控制
1:在pom.xml中添加依赖 <!-- 身份验证 --> <dependency> <groupId>org.springframework.security&l ...
- select2插件placeholder不显示的问题
如果设置了select2的templateSelection,没做特殊处理的话placeholder会不显示,需要做特殊处理 templateSelection: function(repo){ if ...