zoukankan      html  css  js  c++  java
  • netty-socket.io点对点通讯和聊天室通讯

    netty-socketio是基于netty的socket.io服务实现,可以无缝对接前端使用的socketio-client.js。 
    相对于javaee的原生websocket支持(@serverEndpoint)和spring-boot的MessageBroker(@messageMapping),netty-socketio绝对是最好用的websocket后台实现。因为netty-socketio完整的实现了socket.io提供的监听前台事件、向指定客户端发送事件、将指定客户端加入指定房间、向指定房间广播事件、客户端从指定房间退出等操作。

    msg实体

    package com.song.netty;
    
    import java.io.Serializable;
    
    public class Msg implements Serializable{
        private static final long serialVersionUID = -6519304261259719883L;
    
        private String userId;
    
        private String userName;
    
        private String receiveUserId;
    
        private String content;
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getReceiveUserId() {
            return receiveUserId;
        }
    
        public void setReceiveUserId(String receiveUserId) {
            this.receiveUserId = receiveUserId;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public Msg(String userId, String userName, String receiveUserId, String content) {
            super();
            this.userId = userId;
            this.userName = userName;
            this.receiveUserId = receiveUserId;
            this.content = content;
        }
    
        public Msg() {
            super();
        }
    
    
    }

    聊天室通讯服务端可与多个客户端通讯

    测试方法,在不同浏览器各打开一个聊天室页面,发送消息,全部都会接收到

    监听聊天室通讯事件

    package com.song.netty;
    
    import com.corundumstudio.socketio.AckRequest;
    import com.corundumstudio.socketio.SocketIOClient;
    import com.corundumstudio.socketio.SocketIOServer;
    import com.corundumstudio.socketio.listener.DataListener;
    
    public class OneToManyChartListener implements DataListener<Msg>{
    
        SocketIOServer server;
    
        public void setServer(SocketIOServer server) {
            this.server = server;
        }
    
        public void onData(SocketIOClient socketIoClient, Msg msg, AckRequest askSender) throws Exception {
            System.out.println("一对多"+socketIoClient.getSessionId());
            // chatevent为 事件的名称, data为发送的内容
            this.server.getBroadcastOperations().sendEvent("chatMany", msg);
        }
    }

     点对点通讯客户端只与服务端通讯

    测试方法,在不同浏览器各打开一个聊天室页面,发送消息,只有发送消息的那个客服端才能接收到消息

    监听点对点通讯事件

    package com.song.netty;
    
    import com.corundumstudio.socketio.AckRequest;
    import com.corundumstudio.socketio.SocketIOClient;
    import com.corundumstudio.socketio.SocketIOServer;
    import com.corundumstudio.socketio.listener.DataListener;
    
    public class OneToOneChartListener implements DataListener<Msg>{
    
        SocketIOServer server;
    
        public void setServer(SocketIOServer server) {
            this.server = server;
        }
    
        public void onData(SocketIOClient socketIoClient, Msg msg, AckRequest askSender) throws Exception {
            System.out.println("一对一"+socketIoClient.getSessionId());
            // chatevent为 事件的名称, data为发送的内容
            this.server.getClient(socketIoClient.getSessionId()).sendEvent("chatOne", msg);
        }
    }

    客户端使用socket.io,首先启动server,推送消息时服务端获取客户端,向客户端发送消息。客户端接收消息后刷新页面数据。

    package com.song.netty;
    
    import com.corundumstudio.socketio.Configuration;
    import com.corundumstudio.socketio.SocketIOServer;
    
    public class MsgServer {
        public static void main(String[] args) throws InterruptedException {
            Configuration config = new Configuration();
            config.setHostname("localhost");
            config.setPort(8888);
            SocketIOServer server = new SocketIOServer(config);
            OneToOneChartListener listner = new OneToOneChartListener();
            listner.setServer(server);
            OneToManyChartListener listnerMany = new OneToManyChartListener();
            listnerMany.setServer(server);
            // chatOne,chatMany为事件名称
            server.addEventListener("chatOne", Msg.class, listner);
            server.addEventListener("chatMany", Msg.class, listnerMany);
            //启动服务
            server.start();
            Thread.sleep(Integer.MAX_VALUE);
            server.stop();
        }
    }

    特别注意netty的版本,版本过低会导致使用socket.io通讯时跨域

    <dependency>
        <groupId>com.corundumstudio.socketio</groupId>
        <artifactId>netty-socketio</artifactId>
        <version>1.7.14</version>
    </dependency>

    跨域错误如下

    XMLHttpRequest cannot load http://myserver/socket.io/1/?t=1400445162388. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'myclient.com' is therefore not allowed access.

    前台测试页面代码一对一

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="GB2312">
    <title>聊天室</title><base>
    <script src="jquery-1.9.1.js" type="text/javascript"></script>
    <script type="text/javascript" src="socket.io.js"></script>
    <script src="ckeditor/ckeditor.js"></script>
    <style>
    body {
        padding: 20px;
    }
    #console {
        height: 450px;
        overflow: auto;
    }
    .username-msg {
        color: orange;
    }
    .connect-msg {
        color: green;
    }
    .disconnect-msg {
        color: red;
    }
    .send-msg {
        color: #888
    }
    </style>
    </head>
    <body>
        <h1>聊天室</h1>
        <!-- <br /> -->
        <div id="console" class="well"></div>
        <form class="well form-inline" onsubmit="return false;">
            <input id="name"  class="input-xlarge" type="hidden" placeholder="用户名称. . . " />
            <!-- <input id="msg" class="input-xlarge" type="text" placeholder="发送内容. . . " /> -->
            <textarea id="msg" rows="10" cols="50" placeholder="发送内容. . . "></textarea>
            <button type="button" onClick="sendMessage()" class="btn">发送</button>
            <button type="button" onClick="sendDisconnect()" class="btn">下线</button>
            <button type="button" onClick="reloadThis()" class="btn">重连</button>
        </form>
    </body>
    <script type="text/javascript">
    var editor = CKEDITOR.replace( 'msg' );
    editor.on("instanceReady",function(){
        /* this.document.onkeydown=function(event){
             alert(0);
             var e = event || window.event || arguments.callee.caller.arguments[0];
    
             if(event.ctrlKey&&event.keyCode==13){ // enter 键
                 //要做的事情
                 paraent.sendMessage();
             }
        };  */
        this.document.on("keydown",function(){
            //console.log(window.frames[0]);
            var event = window.frames[0].event;
              if(event.ctrlKey&&event.keyCode==13){ // enter 键
                 //要做的事情
                sendMessage();
             } 
        });
    });
    
    var socket;
    connect();
    //var socket = io.connect('http://192.168.0.207:9092');
    
    
    function connect(){
        socket = io.connect('ws://127.0.0.1:9092');
        $("#name").val("你的小宝贝儿"+parseInt(Math.random()*100+1, 10));
    
        socket.on('connect',function() {
            serverOutput('<span class="connect-msg">欢迎进入聊天室!</span>');
            //serverOutput('<span class="disconnect-msg">'+$("#name").val()+'已上线! </span>');
            socket.emit('chatOne', {
                userId:1,
                userName : $("#name").val(),
                receiveUserId:2,
                content : "已上线!"
            });
        });
    
        socket.on('chatOne', function(data) {
            output('<span class="username-msg">'+'<img  src="images/head.jpg" height="64" width="64"/>' + data.userName + ' : </span>'
                    + data.content);
            //editor.setData("");
            //editor.updateElement();
        });
    
        socket.on('disconnect',function() {
            serverOutput('<span class="disconnect-msg">'+$("#name").val()+'已下线! </span>');
    
        });
    }
    
    function reloadThis(){
        socket.disconnect();
        connect();
        console.log(socket);
    }
    
    function sendDisconnect() {
        socket.emit('chatOne', {
            userId:1,
            userName : $("#name").val(),
            receiveUserId:2,
            content : "已下线!"
        });
        socket.disconnect();
    }
    
    function sendMessage() {
        var userName = $("#name").val()
        var message = editor.getData();
        $('#msg').val('');
        socket.emit('chatOne', {
            userId:1,
            userName : userName,
            receiveUserId:2,
            content : message
        });
        //editor.setData("");
    }
    
    function output(message) {
        var currentTime = "<span class='time' >" + new Date() + "</span>";
        var element = $("<div>" +" "  + message + "</div>");
        $('#console').prepend(element);
    }
    
    function serverOutput(message){
        var element = $("<div>" + message + "</div>");
        $('#console').prepend(element);
    }
    
    document.onkeydown=function(event){
        //alert(0);
        var e = event || window.event || arguments.callee.caller.arguments[0];
    
        if(event.ctrlKey&&event.keyCode==13){ // enter 键
            //要做的事情
            sendMessage();
        }
    }; 
    </script>
    </html>

    聊天室页面

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="GB2312">
    <title>聊天室</title><base>
    <script src="jquery-1.9.1.js" type="text/javascript"></script>
    <script type="text/javascript" src="socket.io.js"></script>
    <script src="ckeditor/ckeditor.js"></script>
    <style>
    body {
        padding: 20px;
    }
    #console {
        height: 450px;
        overflow: auto;
    }
    .username-msg {
        color: orange;
    }
    .connect-msg {
        color: green;
    }
    .disconnect-msg {
        color: red;
    }
    .send-msg {
        color: #888
    }
    </style>
    </head>
    <body>
        <h1>聊天室</h1>
        <!-- <br /> -->
        <div id="console" class="well"></div>
        <form class="well form-inline" onsubmit="return false;">
            <input id="name"  class="input-xlarge" type="hidden" placeholder="用户名称. . . " />
            <!-- <input id="msg" class="input-xlarge" type="text" placeholder="发送内容. . . " /> -->
            <textarea id="msg" rows="10" cols="50" placeholder="发送内容. . . "></textarea>
            <button type="button" onClick="sendMessage()" class="btn">发送</button>
            <button type="button" onClick="sendDisconnect()" class="btn">下线</button>
            <button type="button" onClick="reloadThis()" class="btn">重连</button>
        </form>
    </body>
    <script type="text/javascript">
    var editor = CKEDITOR.replace( 'msg' );
    editor.on("instanceReady",function(){
        /* this.document.onkeydown=function(event){
             alert(0);
             var e = event || window.event || arguments.callee.caller.arguments[0];
    
             if(event.ctrlKey&&event.keyCode==13){ // enter 键
                 //要做的事情
                 paraent.sendMessage();
             }
        };  */
        this.document.on("keydown",function(){
            //console.log(window.frames[0]);
            var event = window.frames[0].event;
              if(event.ctrlKey&&event.keyCode==13){ // enter 键
                 //要做的事情
                sendMessage();
             } 
        });
    });
    
    var socket;
    connect();
    //var socket = io.connect('http://192.168.0.207:9092');
    
    
    function connect(){
        socket = io.connect('ws://127.0.0.1:9092');
        $("#name").val("你的小宝贝儿"+parseInt(Math.random()*100+1, 10));
    
        socket.on('connect',function() {
            serverOutput('<span class="connect-msg">欢迎进入聊天室!</span>');
            //serverOutput('<span class="disconnect-msg">'+$("#name").val()+'已上线! </span>');
            socket.emit('chatMany', {
                userId:1,
                userName : $("#name").val(),
                receiveUserId:2,
                content : "已上线!"
            });
        });
    
        socket.on('chatMany', function(data) {
            output('<span class="username-msg">'+'<img  src="images/head.jpg" height="64" width="64"/>' + data.userName + ' : </span>'
                    + data.content);
            //editor.setData("");
            //editor.updateElement();
        });
    
        socket.on('disconnect',function() {
            serverOutput('<span class="disconnect-msg">'+$("#name").val()+'已下线! </span>');
    
        });
    }
    
    function reloadThis(){
        socket.disconnect();
        connect();
        console.log(socket);
    }
    
    function sendDisconnect() {
        socket.emit('chatMany', {
            userId:1,
            userName : $("#name").val(),
            receiveUserId:2,
            content : "已下线!"
        });
        socket.disconnect();
    }
    
    function sendMessage() {
        var userName = $("#name").val()
        var message = editor.getData();
        $('#msg').val('');
        socket.emit('chatMany', {
            userId:1,
            userName : userName,
            receiveUserId:2,
            content : message
        });
        //editor.setData("");
    }
    
    function output(message) {
        var currentTime = "<span class='time' >" + new Date() + "</span>";
        var element = $("<div>" +" "  + message + "</div>");
        $('#console').prepend(element);
    }
    
    function serverOutput(message){
        var element = $("<div>" + message + "</div>");
        $('#console').prepend(element);
    }
    
    document.onkeydown=function(event){
        //alert(0);
        var e = event || window.event || arguments.callee.caller.arguments[0];
    
        if(event.ctrlKey&&event.keyCode==13){ // enter 键
            //要做的事情
            sendMessage();
        }
    }; 
    </script>
    </html>

     源码链接

  • 相关阅读:
    PAT 甲级 1002 A+B for Polynomials (25 分)
    数字提取——C语言
    粒子动画——Pygame
    李白打酒——C++
    C语言输出格雷码
    特殊篮子问题——C语言暴力破解
    黑白迷宫问题——深度优先搜索算法
    最近素数问题——C语言
    巧克力分配问题——C语言
    离散数学——逻辑推理系统
  • 原文地址:https://www.cnblogs.com/MrSong97/p/8509453.html
Copyright © 2011-2022 走看看