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>

 源碼鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM