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>

源码链接

原文地址:https://www.cnblogs.com/MrSong97/p/8509453.html

时间: 2024-10-16 05:41:31

netty-socket.io点对点通讯和聊天室通讯的相关文章

使用node.js和socket.io实现多人聊天室

刚学node.js,想着做点东西练练手.网上的东西多而杂,走了不少弯路,花了一天时间在调代码上.参考网上的一篇文章,重写了部分代码,原来的是基于基于node-websocket-server框架的,我没用框架,单单是socket.io. 一.基本功能 1.用户随意输入一个昵称即可登录2.登录成功后1) 对正在登录用户来说,罗列所有在线用户列表,罗列最近的历史聊天记录2) 对已登录的用户来说,通知有新用户进入房间,更新在线用户列表3.退出登录1)支持直接退出2) 当有用户退出,其他所有在线用户会收

Node.js websocket 使用 socket.io库实现实时聊天室

认识websocket WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duple).一开始的握手需要借助HTTP请求完成. 其实websocket 并不是很依赖Http协议,它也拥有自己的一套协议机制,但在这里我们需要利用的socket.io 需要依赖到http . 之前用java jsp写过一个聊天,其实实现逻辑并不难,只是大部分时间都用在UI的设计上,其实现原理就是一个基于websocket的通信,要想做一个好的聊天室,我觉得大部

vue + socket.io实现一个简易聊天室

vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位大大指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

socket.io入门,简易聊天室

介绍 通常我们web使用的是http协议,但是 HTTP 协议有一个缺陷:通信只能由客户端发起. 所以我们需要一个可以由服务端主动发出的协议,即WebSocket. WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种. Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯.通知与消息推送,实时分析等场景中有较为广泛的应用. socket.io 包含两个

nodejs 实例 使用 Express + Socket.IO 搭建多人聊天室

https://cnodejs.org/topic/51d51cd8d44cbfa3047926ba 作者 nswbmw 详细内容大家可以看这个. 由于时间久远,很多代码都过期了.我刚更新了app.js代码. /** * Module dependencies. */ var express = require('express') , http = require('http') , path = require('path'); var app = express(); // all env

以C#编写的Socket服务器的Android手机聊天室Demo

 内容摘要  1.程序架构    2.通信协议    3.服务器源代码    4.客户端源代码    5.运行效果  一.程序架构 在开发一个聊天室程序时,我们可以使用Socket.Remoting.WCF这些具有双向通信的协议或框架.而现在,我正要实现一个C#语言作为服务器端.Android作为客户端的聊天室.由于服务器端和客户端不是同一语言(C#和java),所有我选择了Socket作为通信协议. 图1.1所示,我们可以看出:android手机客户端A向服务器端发送消息,服务器端收到消息后,

H5+MUI+Node.js+Socket.io群组即时聊天+发送图片+图片压缩

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title

基于Node.js + socket.io实现WebSocket的聊天DEMO

原文摘自我的前端博客,欢迎大家来访问 http://hacke2.github.io 简介 最近看Node.js和HTML5,练手了一个简易版的聊天DEMO,娱乐一下 为什么需要socket.io? node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一, 为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验, 于是socket.io诞生. 简答来说socket.io具体以下特点: 1.socket.io设计的目标是支持任何的浏览器

node.js和socket.io纯js实现的即时通讯实例分享

在这个例子中,其实node.js并没有真正起到服务器的作用,因为我们这里可以直接运行client.html文件,而不用输入url请求,当 然,要想输入url请求页面内容还需要加入请求静态文件的代码.这个实例中node.js最重要的作用就是将服务端迁移到了js,实现了客户端和服务端语 言上的统一,我们只要在浏览器上同时运行两个client.html客户端页面,即可进行简单的即是通讯了,socket.io才是我们真正用来实现即时 通讯的消息的收发. var server = http.createS