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>

  

posted @ 2019-11-26 13:48  冬天不眠  阅读(1725)  评论(0编辑  收藏  举报