springmvc 整合 netty-socketio

摘要:
1mavencom.corundumstudio.socketionetty-socketio1.7.122为了使服务运行启动需要实现ApplicationListener重写里面的方法onApplicationEventi

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("错误:
" + 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);
                    }
                }
            }

        }
    }


}

4MessageInfo.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》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux 常用操作以及概念Python 操作 MySQL 的5种方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

门户系统整合sso cookie共享及显示用户信息

1.1 门户系统整合sso 在门户系统点击登录连接跳转到登录页面。登录成功后,跳转到门户系统的首页,在门户系统中需要从cookie中 把token取出来。所以必须在登录成功后把token写入cookie。并且cookie的值必须在系统之间能共享。 1.1.1 Cookie共享: 1、Domain:必须是相同的。 例如有多个域名: www.taotao....

re库的使用

一、re库的调用 import re 二、正则表达式类型 raw string类型(原生字符串类型,即不包括转义符类型):r'text' string类型,更繁琐。 三、Re库主要功能函数 函数              说明 re.search()        在一个字符串中搜索匹配正则表达式的第一个位置,然后返回match对象 re.match(...

c#实现http请求并解析返回之json

   C#是通过HttpWebRequest类和HttpWebResponseL类来实现http请求的发出和http响应的接收的,由于本人刚用这两个类,不是太熟悉,所以属性和方法就不在这里给大家讲解了。        代码如下: using System; using System.Collections.Generic; using System.Lin...

WINCE中选择目录组件(C#)

因为项目需要一个选择目录的功能,然.NET中在WINCE中folderBrowserDialog组件却不可用,在网上搜了2天都没找到此类可用资源,更搞的是有个资源说是通过导入Shell32.dll的API方式来调用,为引足足浪费半天时间也没找到WINCE平台上的Shell32.dll究竟在何处!不得已,只好自己写个,没想到2个多小时就搞定了,真搞不懂这么简...

【Springboot】Springboot整合邮件服务(HTML/附件/模板-QQ、网易)

介绍 邮件服务是常用的服务之一,作用很多,对外可以给用户发送活动、营销广告等;对内可以发送系统监控报告与告警。 本文将介绍Springboot如何整合邮件服务,并给出不同邮件服务商的整合配置。 如图所示:   Springboot整合邮件服务 开发过程 Springboot搭建 Springboot的搭建非常简单,我们使用 Spring Init...

kafka springboot (或 springcloud ) 整合

狂创客圈 经典图书 : 《Netty Zookeeper Redis 高并发实战》 面试必备 + 面试必备 + 面试必备 【博客园总入口 】 疯狂创客圈 经典图书 : 《SpringCloud、Nginx高并发核心编程》 大厂必备 + 大厂必备 + 大厂必备 【博客园总入口 】 入大厂+涨工资必备: 高并发【 亿级流量IM实战】 实战系列 【 Sprin...