文档章节

nettysocetio-demo2(nettysocetio通讯,两客户端聊天,群发消息改造)

RobertZhou
 RobertZhou
发布于 11/18 12:27
字数 1400
阅读 11
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

前言:
    网上大多数都是只能群发,或者只能发给自己.并没有一个案例完整的群发并且又可以客户端之间聊天的案例,特此改造好的案例给大家分享一下.只要是一对一聊天,一对多群发. 此案例是在服务器端接口方式.

内容:

    此demo更直观传递实体类数据,直接上代码:创建一个maven项目,并且把代码复制过去.

第一:实体类

import lombok.Data;
import java.util.UUID;

@Data
public class Message {
    //源客户端id
    private String clientId;
    //源客户端名字
    private String clientName;
    //sessionId
    private UUID sessionId;
    //目标客户端id
    private String targetClientId;
    //目标客户端名字
    private String targetClientName;
    //目标客户端sessionId
    private UUID targetSessionId;
    //消息类型
    private String messageType;
    //消息类型
    private String messageTime;

    //消息类型
    private String xMessageContent;

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getClientName() {
        return clientName;
    }

    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    public UUID getSessionId() {
        return sessionId;
    }

    public void setSessionId(UUID sessionId) {
        this.sessionId = sessionId;
    }

    public String getTargetClientId() {
        return targetClientId;
    }

    public void setTargetClientId(String targetClientId) {
        this.targetClientId = targetClientId;
    }

    public String getTargetClientName() {
        return targetClientName;
    }

    public void setTargetClientName(String targetClientName) {
        this.targetClientName = targetClientName;
    }

    public UUID getTargetSessionId() {
        return targetSessionId;
    }

    public void setTargetSessionId(UUID targetSessionId) {
        this.targetSessionId = targetSessionId;
    }

    public String getMessageType() {
        return messageType;
    }

    public void setMessageType(String messageType) {
        this.messageType = messageType;
    }

    public String getMessageTime() {
        return messageTime;
    }

    public void setMessageTime(String messageTime) {
        this.messageTime = messageTime;
    }

    public String getxMessageContent() {
        return xMessageContent;
    }

    public void setxMessageContent(String xMessageContent) {
        this.xMessageContent = xMessageContent;
    }

    public Message(String clientId, String clientName, UUID sessionId, String targetClientId, String targetClientName, UUID targetSessionId, String messageType, String messageTime, String xMessageContent) {
        this.clientId = clientId;
        this.clientName = clientName;
        this.sessionId = sessionId;
        this.targetClientId = targetClientId;
        this.targetClientName = targetClientName;
        this.targetSessionId = targetSessionId;
        this.messageType = messageType;
        this.messageTime = messageTime;
        this.xMessageContent = xMessageContent;
    }
    public Message() {
        super();
    }
}

 

第二:监听

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@Component
@Slf4j
public class MessageEventHandler {

    @Autowired
    private SocketIOServer socketIoServer;

    //public static ConcurrentMap<String, SocketIOClient> socketIOClientMap = new ConcurrentHashMap<>();

    /**
     * 客户端连接的时候触发
     *
     * @param client
     */
    @OnConnect
    public void onConnect(SocketIOClient client) {

        //连接服务器初始化值
        String clientId = client.getHandshakeData().getSingleUrlParam("clientId");
        String clientName = client.getHandshakeData().getSingleUrlParam("clientName");
        Message msg = new Message(clientId,
                clientName,
                client.getSessionId(),
                null,
                null,
                null,
                "connect",
                getDate(),
                getXMessageContent()
        );

        //发送给连接成功的客户端,并且发送SessionId给客户端
        //socketIoServer.getClient(client.getSessionId()).sendEvent("messageevent",msg);

        //回发消息
        client.sendEvent("messageevent", msg);
        //client.sendEvent("messageevent", client.getSessionId() +"已连接");
        //System.out.println("客户端:" + client.getSessionId() + "已连接,\n msg=" + msg);
    }

    //消息模型
    private String getXMessageContent() {
        String msgModel = "<xmsg></xmsg>";
        return msgModel;
    }

    //取时间
    private String getDate() {
        long currentTime = System.currentTimeMillis();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd-HHmmss");

        Date date = new Date(currentTime);

        System.out.println(formatter.format(date));

        return formatter.format(date);
    }

    /**
     * 客户端关闭连接时触发
     *
     * @param client
     */
    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        Message msg = new Message(null,
                null,
                null,
                null,
                null,
                null,
                "disconnect",
                getDate(),
                null
        );
        //回发消息
        client.sendEvent("messageevent", msg);
        client.sendEvent("messageevent", "断开连接");
        System.out.println("客户端:" + client.getSessionId() + "断开连接");
    }

    /**
     * 客户端事件
     *
     * @param client   客户端信息
     * @param request 请求信息
     * @param data     客户端发送数据
     */
    @OnEvent(value = "messageevent")
    public void onEvent(SocketIOClient client, AckRequest request, Message data) {
        System.out.println("发来消息:" + data);

        //发送给指定客户端
        socketIoServer.getClient(data.getTargetSessionId()).sendEvent("messageevent",data);

        //发送给自己客户端
        socketIoServer.getClient(client.getSessionId()).sendEvent("messageevent",data);

        //广播消息
        //sendBroadcast();
    }

    /**
     * 广播消息
     */
    /*public void sendBroadcast() {
        for (SocketIOClient client : socketIOClientMap.values()) {
            if (client.isChannelOpen()) {
                client.sendEvent("Broadcast", "当前时间", System.currentTimeMillis());
            }
        }

    }*/
}

 

第三:服务器

import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class NettySocketioConfig {
    /**
     * netty-socketio服务器
     */
    @Bean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setHostname("localhost");
        config.setPort(9092);

        SocketIOServer server = new SocketIOServer(config);
        return server;
    }

    /**
     * 用于扫描netty-socketio的注解,比如 @OnConnect、@OnEvent
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner() {
        return new SpringAnnotationScanner(socketIOServer());
    }
}

 

第四:启动类

import com.corundumstudio.socketio.SocketIOServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Slf4j
public class NettySocketioApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(NettySocketioApplication.class, args);
    }

    @Autowired
    private SocketIOServer socketIOServer;

    @Override
    public void run(String... strings) {
        socketIOServer.start();
        System.out.println("socket.io启动成功!");
    }
}

 

第五:HTML客户端

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>websocket-java-socketio</title>
    <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
</head>
<body>
<h1>Socket.io Test</h1>
<div><p id="status">Waiting for input</p></div>
<div><p id="message">hello world!</p></div>
<input id="sessionId" class="input-xlarge" type="text" placeholder="谁发送?" />
<input id="targetSessionId" class="input-xlarge" type="text" placeholder="发送给谁?" /></br>
<button id="connect" onClick='connect()'/>Connect</button>
<button id="disconnect" onClick='disconnect()'>Disconnect</button>
<button id="send" onClick='send()'/>Send Message</button>
</body>

<script type="text/javascript">

    /**
     * 前端js的 socket.emit("事件名","参数数据")方法,是触发后端自定义消息事件的时候使用的,
     * 前端js的 socket.on("事件名",匿名函数(服务器向客户端发送的数据))为监听服务器端的事件
     **/

        //初始化URL
        //源客户端ID
    var clientId="123456";
    //源客户端名字
    var clientName="张三";
    //sessionId
    var sessionId=null;
    //目标客户端id
    var targetClientId=null;
    //目标客户端名字
    var targetClientName=null;
    //目标客户端sessionId
    var targetSessionId=null;
    //消息类型
    var messageType=null;
    //消息类型
    var messageTime=null;
    //消息类型
    var xMessageContent=null;

    var url = "http://localhost:9092?clientId="+clientId+"&"+"clientName="+clientName;
    var socket = io.connect(url);
    var firstconnect = true;

    function connect() {
        if(firstconnect) {

            //socket.on('reconnect', function(){ status_update("Reconnected to Server"); });
            //socket.on('reconnecting', function( nextRetry ){ status_update("Reconnecting in "
            //+ nextRetry + " seconds"); });
            //socket.on('reconnect_failed', function(){ message("Reconnect Failed"); });
            //firstconnect = false;
        } else {
            socket.socket.reconnect();
        }
    }

    //监听服务器连接事件
    socket.on('connect', function(){ status_update("Connected to Server"); });
    //监听服务器关闭服务事件
    socket.on('disconnect', function(){ status_update("Disconnected from Server"); });
    //监听服务器端发送消息事件
    socket.on('messageevent', function(data) {
        message(data)
        //console.log("服务器发送的消息是:"+data);
    });

    //断开连接
    function disconnect() {
        socket.disconnect();
    }

    function message(data) {
        document.getElementById('message').innerHTML = "Server says: " + data;
    }

    function status_update(txt){
        document.getElementById('status').innerHTML = txt;
    }

    function esc(msg){
        return msg.replace(/</g, '<').replace(/>/g, '>');
    }
    //点击发送消息触发
    function send() {
        console.log("点击了发送消息,开始向服务器发送消息")
        var msg = {
            clientId:clientId,
            clientName:clientName,
            sessionId:document.getElementById('sessionId').value,
            targetClientId:targetClientId,
            targetClientName:targetClientName,
            targetSessionId:document.getElementById('targetSessionId').value,
            messageType:messageType,
            messageTime:null,
            xMessageContent:null
        };
        socket.emit('messageevent', msg);
    };
</script>
</html>

 

总结:此demo2偏向于接口方式,Vue,Wux,uni-app等整合起来相对易于整合. 本demo是对于一对一聊天,群发聊天等.

© 著作权归作者所有

RobertZhou
粉丝 12
博文 172
码字总数 22800
作品 0
广州
程序员
私信 提问
nettysocetio-demo1(nettysocetio通讯,两客户端聊天,群发消息改造)

前言: 网上大多数都是只能群发,或者只能发给自己.并没有一个案例完整的群发并且又可以客户端之间聊天的案例,特此改造好的案例给大家分享一下.只要是一对一聊天,一对多群发. 内容: 废话不多说...

RobertZhou
11/18
12
0
androidpn 作为Android推送方案存在的问题

如果百度或者Google搜索 “android 推送” 关键字,相当一部分文章都在说到 androidpn。也可以看到有人说用起来了,有人在吐槽说不稳定、功能缺失,维护工作量大。本文尝试对 androidpn 的前...

极光推送
2012/11/19
12.2K
94
基于 JavaFX 开发的聊天客户端 - OIM

一、简介 OIM是一套即时通讯的聊天系统,在这里献给大家,一方面希望能够帮助对即时通讯有兴趣研究的朋友,希望我们能够共同进步,另一个就是希望能够帮助到需要即时通讯系统的朋友或者企业,...

烙灵
2017/06/09
27.8K
47
音视频和数据传输的局域网通讯

随着全球信息化进程的不断发展,越来越多的企业使用局域网来管理各种事务。但随着局域网的机器增多,软件的应用对局域网的信息吞吐、处理能力的要求也越高。为解决上述矛盾,就有必要设计一个...

AnyChat
2014/12/19
704
0
CIM 2.2.0 发布,新增 Java 版本客户端

CIM 2.2.0 发布了,基于Java服务端的即时通信解决方案,与android 客户端完美结合,同时支持其他语言的移动应用,桌面应用,以及后台系统之间的即时消交互,为你解决了长连接各种消息事件,断...

远方夕阳
2016/07/18
2.4K
3

没有更多内容

加载失败,请刷新页面

加载更多

计算机电子书 2018 BiliDrive 备份

下载方式 根据你的操作系统下载不同的 BiliDrive 二进制。 执行: bilidrive download <link> 链接 <!--more--> 文档 链接 Webpack 中文指南.epub (409.01 KB) bdrive://ce58b7b58292296a61......

ApacheCN_飞龙
44分钟前
4
0
js转义字符串

js转义字符串 转义 字符串转义,简单粗暴的方法encodeURIComponent; encodeURIComponent 转义除了字母、数字、(、)、.、!、~、*、'、-和_之外的所有字符。 解码方法 decodeURIComponent(enc...

DrChenXX
47分钟前
4
0
在CentOS7搭建Redis哨兵服务

记一次搭建Redis哨兵服务(一主两从三哨兵) 1、下载Redis安装包http://www.redis.cn/download.html下载最新版,本次文档使用的是redis-5.0.6 2、准备三台虚拟机并且依次创建redis用户。设置...

jxgshxs
56分钟前
3
0
如何在单引号引起来的字符串中转义单引号

假设您有一个Bash alias例如: alias rxvt='urxvt' 效果很好。 然而: alias rxvt='urxvt -fg '#111111' -bg '#111111'' 将不起作用,也不会: alias rxvt='urxvt -fg \'#111111\' -bg \'......

技术盛宴
今天
5
0
网络时间服务和 chrony

网络时间服务和 chrony ntp 服务 chrony 服务 公共 NTP 服务 时间工具 ntp 服务 ntp 既可作客户端也可做服务器,需要时时开启与服务器同步,也需要时时等待客户端的连接,因此不同与c/s 结构...

hardstudy-win
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部