基于J-IM发送消息

什么是j-im

J-IM 是用JAVA语言,基于t-io开发的轻量、高性能、单机支持几十万至百万在线用户IM,主要目标降低即时通讯门槛,快速打造低成本接入在线IM系统,通过极简洁的消息格式就可以实现多端不同协议间的消息发送如内置(http、websocket、tcp自定义im协议)等,并提供通过http协议的api接口进行消息发送无需关心接收端属于什么协议,一个消息格式搞定一切!

消息格式

  1. 聊天请求消息请求结构
{
   "from": "来源ID",
   "to": "目标ID",
   "cmd":"命令码(11)int类型",
   "createTime": "消息创建时间long类型",
   "msgType": "消息类型int类型(0:text、1:image、2:voice、3:vedio、4:music、5:news)",
   "chatType":"聊天类型int类型(0:未知,1:公聊,2:私聊)",
   "groupId":"群组id仅在chatType为(1)时需要,String类型",
   "content": "内容"
}
请求:COMMAND_CHAT_REQ(11) 响应:COMMAND_CHAT_RESP(12)
  1. 鉴权请求消息请求结构
{
    "cmd":"命令码(3)int类型",
    "token": "校验码"
}
请求:COMMAND_AUTH_REQ(3) 响应:COMMAND_AUTH_RESP(4)
  1. 握手请求消息请求结构
{
    "cmd":"命令码(1)int类型",
    "hbyte":"握手1个字节"
}
说明:请求:COMMAND_HANDSHAKE_REQ(1) 响应:COMMAND_HANDSHAKE_RESP(2)
  1. 登录请求消息请求结构
{
    "cmd":"命令码(5)int类型",
    "userId": "用户账号",
    "password": "密码",
    "token": "校验码(此字段可与userId、password共存,也可只选一种方式)"
}
请求:COMMAND_LOGIN_REQ(5) 响应:COMMAND_LOGIN_RESP(6)
  1. 心跳请求消息请求结构
{
    "cmd":"命令码(13)int类型",
    "hbbyte":"心跳1个字节"
}
请求:COMMAND_HEARTBEAT_REQ(13) 响应:COMMAND_HEARTBEAT_REQ(13)
  1. 关闭、退出请求消息请求结构
{
    "cmd":"命令码(14)int类型",
    "userId":"用户Id"
}
请求:COMMAND_CLOSE_REQ(14) 响应:
  1. 获取用户信息请求结构
{
     "cmd":"命令码(17)int类型",
     "userId":"用户id(必填项)",
     "type":"获取类型(0:所有在线用户,1:所有离线线用户,2:所有用户[在线+离线])"
}
请求:COMMAND_GET_USER_REQ(17) 响应:COMMAND_GET_USER_RESP(18)
  1. 获取用户消息请求结构
{
     "cmd":"命令码(19)int类型",
     "fromUserId":"消息发送用户id(此字段必须与userId一起使用,获取双方聊天消息),非必填",
     "userId":"当前用户id(必填字段),当只有此字段时,type必须为0,意思是获取当前用户所有离线消息(好友+群组)",
     "groupId":"群组id(此字段必须与userId一起使用,获取当前用户指定群组聊天消息),非必填",
     "beginTime":"消息区间开始时间Date毫秒数double类型,非必填",
     "endTime":"消息区间结束时间Date毫秒数double类型,非必填",
     "offset":"分页偏移量int类型,类似Limit 0,10 中的0,非必填",
     "count":"显示消息数量,类似Limit 0,10 中的10,非必填",
     "type":"消息类型(0:离线消息,1:历史消息)"
}
请求:COMMAND_GET_MESSAGE_REQ(19) 响应:COMMAND_GET_MESSAGE_RESP(20)

websocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

  1. 建立连接
var socket = new WebSocket("ws://localhost:8888/?username=1640769867971&password=123");
  1. WebSocket 事件
//连接建立时触发
socket.onopen = function(e){

};

//客户端接收服务端数据时触发
socket.onmessage = function(e){
  
};
//通信发生错误时触发
socket.onclose = function(e){

};
//连接关闭时触发
socket.onerror = function(e){

};
  1. websocket 方法
//发送数据
var msg;
socket.send(msg);
//关闭连接
WebSocket.close();
  1. websocket 属性
ws.readyState
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

ws.bufferedAmount
只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

springboot项目,使用j-im发消息

  1. 依赖jim-server
 <dependency>
     <groupId>org.j-im</groupId>
     <artifactId>jim-server</artifactId>
     <version>3.0.0.v20200501-RELEASE</version>
</dependency>
  1. 在启动类增加启动jimServer代码
package com.example.demo;

import com.example.demo.command.DemoWsHandshakeProcessor;
import com.example.demo.listener.ImDemoGroupListener;
import com.example.demo.listener.ImDemoUserListener;
import com.example.demo.processor.MyAsyncChatMessageProcessor;
import com.example.demo.service.LoginServiceProcessor;
import org.apache.commons.lang3.StringUtils;
import org.jim.core.packets.Command;
import org.jim.core.utils.PropUtil;
import org.jim.server.JimServer;
import org.jim.server.command.CommandManager;
import org.jim.server.command.handler.ChatReqHandler;
import org.jim.server.command.handler.HandshakeReqHandler;
import org.jim.server.command.handler.LoginReqHandler;
import org.jim.server.config.ImServerConfig;
import org.jim.server.config.PropertyImServerConfigBuilder;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.tio.core.ssl.SslConfig;

import java.io.IOException;

@SpringBootApplication
@MapperScan({"com.example.demo.base.mappers"})
public class DemoApplication {

    public static void main(String[] args) {

        ImServerConfig imServerConfig = null;
        try {
            imServerConfig = new PropertyImServerConfigBuilder("config/jim.properties").build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //初始化SSL;(开启SSL之前,你要保证你有SSL证书哦...)
        try {
            initSsl(imServerConfig);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //设置群组监听器,非必须,根据需要自己选择性实现;
        imServerConfig.setImGroupListener(new ImDemoGroupListener());
        //设置绑定用户监听器,非必须,根据需要自己选择性实现;
        imServerConfig.setImUserListener(new ImDemoUserListener());
        JimServer jimServer = new JimServer(imServerConfig);

        /*****************start 以下处理器根据业务需要自行添加与扩展,每个Command都可以添加扩展,此处为demo中处理**********************************/

        HandshakeReqHandler handshakeReqHandler = CommandManager.getCommand(Command.COMMAND_HANDSHAKE_REQ, HandshakeReqHandler.class);
        //添加自定义握手处理器;
        handshakeReqHandler.addMultiProtocolProcessor(new DemoWsHandshakeProcessor());
        LoginReqHandler loginReqHandler = CommandManager.getCommand(Command.COMMAND_LOGIN_REQ,LoginReqHandler.class);
//		添加登录业务处理器;
        loginReqHandler.setSingleProcessor(new LoginServiceProcessor());
        //添加用户业务聊天记录处理器,用户自己继承抽象类BaseAsyncChatMessageProcessor即可,以下为内置默认的处理器!
        ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ, ChatReqHandler.class);
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
        //业务处理器设置成自己的(为小萨和发消息者绑定关系)
        MyAsyncChatMessageProcessor myAsyncChatMessageProcessor = run.getBean("myAsyncChatMessageProcessor", MyAsyncChatMessageProcessor.class);
        chatReqHandler.setSingleProcessor(myAsyncChatMessageProcessor);
        /*****************end *******************************************************************************************/
        try {
            jimServer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    /**
     * 开启SSL之前,你要保证你有SSL证书哦!
     * @param imServerConfig
     * @throws Exception
     */
    private static void initSsl(ImServerConfig imServerConfig) throws Exception {
        //开启SSL
        if(ImServerConfig.ON.equals(imServerConfig.getIsSSL())){
            String keyStorePath = PropUtil.get("jim.key.store.path");
            String keyStoreFile = keyStorePath;
            String trustStoreFile = keyStorePath;
            String keyStorePwd = PropUtil.get("jim.key.store.pwd");
            if (StringUtils.isNotBlank(keyStoreFile) && StringUtils.isNotBlank(trustStoreFile)) {
                SslConfig sslConfig = SslConfig.forServer(keyStoreFile, trustStoreFile, keyStorePwd);
                imServerConfig.setSslConfig(sslConfig);
            }
        }
    }

}

需要注意的是,上述代码中myAsyncChatMessageProcessor是自己的业务处理器,必须在项目启动后,将myAsyncChatMessageProcessor放在spring容器中,然后再从spring容器取出来。
3. 理论上这样就可以了,但是我在使用的过程中,发消息会有以下错误提示,理论上是不应该这样的。
这是错误信息
于是发现demo项目中与直接依赖jim-serve下载jedis版本不一样,因此修改了pom文件,重新依赖jedis

<dependency>
            <groupId>org.j-im</groupId>
            <artifactId>jim-server</artifactId>
            <version>3.0.0.v20200501-RELEASE</version>
            <exclusions>
                <exclusion>
                   <groupId>redis.clients</groupId>
                   <artifactId>jedis</artifactId>
                </exclusion>
            </exclusions>
</dependency>
<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.3</version>
</dependency>
  1. demo

链接: https://download.csdn.net/download/weixin_44792849/74720662

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值