springboot集成netty-socketio集群实现

本文介绍了如何使用SpringBoot集成Netty-SocketIO来创建一个集群实现即时通讯(IM)。每个IM节点拥有唯一的标识A,由机器码和IM端口号组成。当客户端连接时,其用户ID与服务端标识A绑定。消息发送时,如果接收方在线,直接发送;否则,通过Redis订阅发布机制将消息路由到接收方所在的节点。详细步骤包括配置文件、启动类、工具类等,并提供了代码示例和下载链接。
摘要由CSDN通过智能技术生成

1、实现思路

IM每个节点定义唯一标识A,A = 机器码加im端口号。

当客户端连接到IM节点后,把客户端的用户唯一标识ID和连接的IM服务端的唯一标识A进行绑定。

当两个用户相互发送消息时,判断接收用户是否在线,在线,则获取接收消息用户的socketclient,若获取不到,则根据接收用户ID获取接收用户所在节点的唯一标识。

然后通过redis的订阅发布,发送消息到接收用户所在的节点。每个节点只订阅和该节点唯一标识相同的topic。

2、代码

pom

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.72</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>com.corundumstudio.socketio</groupId>
            <artifactId>netty-socketio</artifactId>
            <version>1.7.18</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.7</version>
        </dependency>


        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.12.0</version>
        </dependency>
    </dependencies>

3、配置文件application.yml

spring:
  redis:
    redisson:
      config:
        classpath:redisson.yaml


server:
  port: 8080

im:
  port: 9092


4、配置文件redisson.yaml

singleServerConfig:
  idleConnectionTimeout: 10000
  connectTimeout: 10000
  timeout: 3000
  retryAttempts: 3
  retryInterval: 1500
  address: redis://192.168.5.174:6379
  password: ld123456
  clientName: null
  keepAlive: false
  tcpNoDelay: false
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode: "NIO"

 

5、启动类

VoiceApplication.java
package com.luding.voice.lib;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class VoiceApplication {

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

}

6、获取机器码工具类

MachineUtil.java
package com.luding.voice.lib.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Scanner;

public class MachineUtil {

    public static String getMechineCode() {
        String property = System.getProperty("os.name").toLowerCase();
        String cpuSerialNumber = "";
        String hardDiskSerialNumber = "";
        String md5Result = "";
        if (property.contains("windows")) {
            // 获取cpu序列号
            cpuSerialNumber = MachineUtil.getCPUSerialNumber();
            // 获取 硬盘号
            hardDiskSerialNumber = MachineUtil.getHardDiskSerialNumber();
        } else if (property.contains("linux")) {
            // 获取cpu序列号
            cpuSerialNumber = MachineUtil.getUUID();
            // 获取 硬盘号
            hardDiskSerialNumber = MachineUtil.getBoisVersion();
        }
        // 获取到cpu序列号和硬盘号
        return cpuSerialNumber + hardDiskSerialNumber;
    }

    /**
     * 获取CPU序列号(Windows)
     *
     * @return
     * @throws IOException
     */
    public static String getCPUSerialNumber() {
        String serial;
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"wmic", "cpu", "get", "ProcessorId"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            serial = sc.next();
            serial = sc.next();
        } catch (IOException e) {
            throw new RuntimeException("获取CPU序列号失败");
        }
        return serial;
    }

    /**
     * 获取 硬盘序列号(Windows)
     *
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public static String getHardDiskSerialNumber() {
        String serial;
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"wmic", "path", "win32_physicalmedia", "get", "serialnumber"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
         
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值