s_demo_src.png (25.03 KB, 下载次数: 7213)
下载附件 保存到相册
5 年前 上传
s_sdk_binary.png (35.29 KB, 下载次数: 7552)
提示:MobileIMSDK的Server端lib包支持Java 1.7(含)及以上版本。
1.png (86.82 KB, 下载次数: 5899)
1 年前 上传
<dependencies> <!-- 依赖的开源JSON库Gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.9</version> </dependency> <!-- 依赖的log4j日志框架的实用组合 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.23.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.23.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.23.1</version> </dependency> <!-- 依赖的RabbitMQ中间件的java客户端库,用于与MobileIMSDK-Web产品进行消息互通时 --> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.20.0</version> </dependency> <!-- 依赖的netty库 --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.67.Final</version> </dependency> <!-- MobileIMSDK的核心库(此jar没有上传到mave中央库,请注意本地引用路径哦) --> <dependency> <groupId>com.x52im</groupId> <artifactId>mobileimsdk-server</artifactId> <version>6.5</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/MobileIMSDKServer.jar</systemPath> </dependency> </dependencies>
2.png (77.66 KB, 下载次数: 5600)
QQ20151119-1.png (38.42 KB, 下载次数: 7465)
10 年前 上传
public class ServerEventListenerImpl implements ServerEventListener { private static Logger logger = LoggerFactory.getLogger(ServerEventListenerImpl.class); /** * 用户身份验证回调方法定义(即验证客户端连接的合法性,合法就允许正常能信,否则断开). * <p> * 服务端的应用层可在本方法中实现用户登陆验证。 * * @param userId 传递过来的准一id,保证唯一就可以通信,可能是登陆用户名、也可能是任意不重复的id等,具体意义由业务层决定 * @param token 用于身份鉴别和合法性检查的token,它可能是登陆密码,也可能是通过前置单点登陆接口拿到的token等,具体意义由业务层决定 * @param extra 额外信息字符串。本字段目前为保留字段,供上层应用自行放置需要的内容 * @param session 此客户端连接对应的 netty “会话” * @return 0 表示登陆验证通过,否则可以返回用户自已定义的错误码,错误码值应为:>=1025的整数 */ @Override public int onUserLoginVerify(String userId, String token, String extra, Channel session) { logger.debug("【DEBUG_回调通知】正在调用回调方法:OnVerifyUserCallBack...(extra=" + extra + ")"); return 0; } /** * 用户登录验证成功后的回调方法定义(在业务上可理解为该用户的上线通知). * <p> * 服务端的应用层通常可在本方法中实现用户上线通知等。 * * @param userId 传递过来的准一id,保证唯一就可以通信,可能是登陆用户名、也可能是任意不重复的id等,具体意义由业务层决定 * @param extra 额外信息字符串。本字段目前为保留字段,供上层应用自行放置需要的内容。为了丰富应用层处理的手段,在本回调中也把此字段传进来了 * @param session 此客户端连接对应的 netty “会话” */ @Override public void onUserLoginSucess(String userId, String extra, Channel session) { logger.debug("【IM_回调通知onUserLoginSucess】用户:" + userId + " 上线了!"); } /** * 用户退出登录回调方法定义(可理解为下线通知回调)。 * <p> * 服务端的应用层通常可在本方法中实现用户下线通知等。 * * @param userId 下线的用户user_id * @param session 此客户端连接对应的 netty “会话” * @param beKickoutCode 被踢原因编码,本参数当为-1时表示本次logout事件不是源自“被踢”,否则被踢原因编码请见 {@link PKickoutInfo}类中的常量定义 * @see {@link OnlineProcessor#setBeKickoutCodeForChannel(Channel, int)} */ @Override public void onUserLogout(String userId, Channel session, int beKickoutCode) { logger.debug("【DEBUG_回调通知onUserLogout】用户:" + userId + " 离线了(beKickoutCode=" + beKickoutCode + ")!"); } /** * 收到客户端发送给“服务端”的数据回调通知(即:消息路径为“C2S”的消息)前的处理逻辑。 * * @param p 消息/指令的完整协议包对象 * @param session 消息发送者的“会话”引用(也就是客户端的网络连接对象) * @return true表示经过本方法后将正常进入 {@link #onTransferMessage4C2S(Protocal, Channel)}继续正常逻辑 ,false表示该条指令将不会继续处理(直接被丢弃) * @see #onTransferMessage4C2S(Protocal, Channel) * @since 6.2 */ @Override public boolean onTransferMessage4C2CBefore(Protocal p, Channel session) { return true; } /** * 收到客户端发送给“其它客户端”的数据回调通知(即:消息路径为“C2C”的消息)前的处理逻辑。 * * @param p 消息/指令的完整协议包对象 * @param session 消息发送者的“会话”引用(也就是客户端的网络连接对象) * @return true表示经过本方法后将正常进入 {@link #onTransferMessage4C2C(Protocal)}继续正常逻辑 ,false表示该条指令将不会继续处理(直接被丢弃) * @see #onTransferMessage4C2C(Protocal) * @since 6.2 */ @Override public boolean onTransferMessage4C2SBefore(Protocal p, Channel session) { return true; } /** * 收到客户端发送给“服务端”的数据回调通知(即:消息路径为“C2S”的消息). * * @param p 消息/指令的完整协议包对象 * @param session 此客户端连接对应的 netty “会话” * @return true表示本方法已成功处理完成,否则表示未处理成功。此返回值目前框架中并没有特殊意义,仅作保留吧 * @see Protocal * @since 4.0 */ @Override public boolean onTransferMessage4C2S(Protocal p, Channel session) { // 接收者uid String userId = p.getTo(); // 发送者uid String from_user_id = p.getFrom(); // 消息或指令内容 String dataContent = p.getDataContent(); // 消息或指令指纹码(即唯一ID) String fingerPrint = p.getFp(); // 【重要】用户定义的消息或指令协议类型(开发者可据此类型来区分具体的消息或指令) int typeu = p.getTypeu(); logger.debug("【DEBUG_回调通知】[typeu=" + typeu + "]收到了客户端" + from_user_id + "发给服务端的消息:str=" + dataContent); return true; } /** * 收到客户端发送给“其它客户端”的数据回调通知(即:消息路径为“C2C”的消息). * * @param p 消息/指令的完整协议包对象 * @see Protocal * @since 4.0 */ @Override public void onTransferMessage4C2C(Protocal p) { // 接收者uid String userId = p.getTo(); // 发送者uid String from_user_id = p.getFrom(); // 消息或指令内容 String dataContent = p.getDataContent(); // 消息或指令指纹码(即唯一ID) String fingerPrint = p.getFp(); // 【重要】用户定义的消息或指令协议类型(开发者可据此类型来区分具体的消息或指令) int typeu = p.getTypeu(); logger.debug("【DEBUG_回调通知】[typeu=" + typeu + "]收到了客户端" + from_user_id + "发给客户端" + userId + "的消息:str=" + dataContent); } /** * 服务端在进行消息发送时,当对方在线但实时发送失败、以及其它各种问题导致消息并没能正常发出时,将无条件走本回调通知。 * * * @param p 消息/指令的完整协议包对象 * @return true表示应用层已经处理了离线消息,否则表示应用层没有处理 * @see Protocal * @see #onTransferMessage4C2C(Protocal) * @since 4.0 */ @Override public boolean onTransferMessage_RealTimeSendFaild(Protocal p) { // 接收者uid String userId = p.getTo(); // 发送者uid String from_user_id = p.getFrom(); // 消息或指令内容 String dataContent = p.getDataContent(); // 消息或指令指纹码(即唯一ID) String fingerPrint = p.getFp(); // 【重要】用户定义的消息或指令协议类型(开发者可据此类型来区分具体的消息或指令) int typeu = p.getTypeu(); logger.debug("【DEBUG_回调通知】[typeu=" + typeu + "]客户端" + from_user_id + "发给客户端" + userId + "的消息:str=" + dataContent + ",因实时发送没有成功,需要上层应用作离线处理哦,否则此消息将被丢弃."); return false; } /** * <b>注意:</b><font color="red">本回调仅用于与Web的互通模式下,默认情况下本方法可什么也不做,无任何影响。如你对此回调有疑问可跟Jack Jiang进行技术讨论!</font> * {@inheritDoc} * * @since 6.2 */ @Override public void onTransferMessage4C2C_AfterBridge(Protocal p) { // 默认本方法可 } }
public class MessageQoSEventS2CListnerImpl implements MessageQoSEventListenerS2C { private static Logger logger = LoggerFactory.getLogger(MessageQoSEventS2CListnerImpl.class); /** * 消息未送达的回调事件通知. * * @param lostMessages 由MobileIMSDK QoS算法判定出来的未送达消息列表(此列表 * 中的Protocal对象是原对象的clone(即原对象的深拷贝),请放心使用哦),应用层 * 可通过指纹特征码找到原消息并可以UI上将其标记为”发送失败“以便即时告之用户 */ @Override public void messagesLost(ArrayList < Protocal > lostMessages) { logger.debug("【DEBUG_QoS_S2C事件】收到系统的未实时送达事件通知,当前共有" + lostMessages.size() + "个包QoS保证机制结束,判定为【无法实时送达】!"); } /** * 消息已被对方收到的回调事件通知. * <p> * <b>目前,判定消息被对方收到是有两种可能:</b><br> * 1) 对方确实是在线并且实时收到了;<br> * 2) 对方不在线或者服务端转发过程中出错了,由服务端进行离线存储成功后的反馈 * (此种情况严格来讲不能算是“已被收到”,但对于应用层来说,离线存储了的消息 * 原则上就是已送达了的消息:因为用户下次登陆时肯定能通过HTTP协议取到)。 * * @param theFingerPrint 已被收到的消息的指纹特征码(唯一ID),应用层可据此ID * 来找到原先已发生的消息并可在UI是将其标记为”已送达“或”已读“以便提升用户体验 */ @Override public void messagesBeReceived(String theFingerPrint) { if(theFingerPrint != null) { logger.debug("【DEBUG_QoS_S2C事件】收到对方已收到消息事件的通知,fp=" + theFingerPrint); } } }
public class ServerLauncherImpl extends ServerLauncher { private static Logger logger = LoggerFactory.getLogger(ServerLauncherImpl.class); /** * 静态类方法:进行一些全局配置设置。 */ static { // 设置MobileIMSDK服务端的UDP网络监听端口 GatewayUDP.PORT = 7901; // 设置MobileIMSDK服务端的TCP网络监听端口 GatewayTCP.PORT = 8901; // 设置MobileIMSDK服务端的WebSocket网络监听端口 GatewayWebsocket.PORT = 3000; // 设置MobileIMSDK服务端同时支持UDP、TCP、WebSocket三种协议 ServerLauncher.supportedGateways = Gateway.SOCKET_TYPE_UDP | Gateway.SOCKET_TYPE_TCP | Gateway.SOCKET_TYPE_WEBSOCKET; // 开/关Demog日志的输出 QoS4SendDaemonS2C.getInstance().setDebugable(true); QoS4ReciveDaemonC2S.getInstance().setDebugable(true); // 与客户端协商一致的心跳频率模式设置 ServerToolKits.setSenseModeTCP(SenseModeTCP.MODE_5S); ServerToolKits.setSenseModeWebsocket(SenseModeWebsocket.MODE_5S); // 关闭与Web端的消息互通桥接器(其实SDK中默认就是false) ServerLauncher.bridgeEnabled = false; // TODO 跨服桥接器MQ的URI(本参数只在ServerLauncher.bridgeEnabled为true时有意义) // BridgeProcessor.IMMQ_URI = "amqp://js:19844713@192.168.0.190"; // 设置最大TCP帧内容长度(不设置则默认最大是 6 * 1024字节) // GatewayTCP.TCP_FRAME_MAX_BODY_LENGTH = 60 * 1024; SslContext sslContext = createSslContext(); // 开启TCP协议的SSL/TLS加密传输(请确保客户端也已开发SSL) // GatewayTCP.sslContext = sslContext; // 开启WebSocket协议的SSL/TLS加密传输(请确保SSL证书是正规CA签发,否则浏览器是不允许的) // GatewayWebsocket.sslContext = sslContext; } /** * 实例构造方法。 * * @throws IOException */ public ServerLauncherImpl() throws IOException { super(); } /** * 初始化消息处理事件监听者. */ @Override protected void initListeners() { // ** 设置各种回调事件处理实现类 this.setServerEventListener(new ServerEventListenerImpl()); this.setServerMessageQoSEventListener(new MessageQoSEventS2CListnerImpl()); } /** * 创建SslContext对象,用于开启SSL/TLS加密传输。 * * @return 如果成功创建则返回SslContext对象,否则返回null */ private static SslContext createSslContext() { try { /** 示例 2:使用证书(证书位于相对路径)*/ // TODO: 注意:请使用自已的证书,Demo中带的证书为自签名证书且已绑定域名,不安全!!! // 证书文件 InputStream certChainFile = ServerLauncherImpl.class.getResourceAsStream("certs/netty-cert2.crt"); // 私钥文件(注意:Netty只支持.pk8格式,如何生成,见JackJiang文章:) InputStream keyFile = ServerLauncherImpl.class.getResourceAsStream("certs/netty-key2.pk8"); // 私钥密码(注意:Netty只支持.pk8格式,如何生成,见JackJiang文章:) String keyPassword = "123456"; // 生成SslContext对象(为了方便理解,此处使用的是单向认证) SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile, keyPassword).clientAuth(ClientAuth.NONE).build(); return sslCtx; } catch (Exception e) { logger.warn("createSslContext()时出错了,原因:" + e.getMessage(), e); } return null; } /** * Demo程序主入口函数。 * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // 实例化后记得startup哦,单独startup()的目的是让调用者可以延迟决定何时真正启动IM服务 final ServerLauncherImpl sli = new ServerLauncherImpl(); // 启动MobileIMSDK服务端的Demo sli.startup(); // 加一个钩子,确保在JVM退出时释放netty的资源 Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { sli.shutdown(); } }); } }
为了配合Android、iOS客户端,Server端也需要进行设置。
// MobileIMSDK核心IM框架的服务端敏感度模式设置 ServerLauncherImpl.setSenseMode(SenseMode.MODE_15S);
s_api_doc.png (104.57 KB, 下载次数: 7473)
1-5.png (32.71 KB, 下载次数: 7466)
1-6.png (34.19 KB, 下载次数: 7403)
1.png (12.07 KB, 下载次数: 6324)
3 年前 上传
2.png (27.42 KB, 下载次数: 6594)
3.png (23.35 KB, 下载次数: 6418)
3.png (106.64 KB, 下载次数: 6627)
5.png (62 KB, 下载次数: 6572)
1111.png (169.67 KB, 下载次数: 1782)
2222.png (86.28 KB, 下载次数: 1613)
来源:即时通讯网 - 即时通讯开发者社区!
轻量级开源移动端即时通讯框架。
快速入门 / 性能 / 指南 / 提问
轻量级Web端即时通讯框架。
详细介绍 / 精编源码 / 手册教程
移动端实时音视频框架。
详细介绍 / 性能测试 / 安装体验
基于MobileIMSDK的移动IM系统。
详细介绍 / 产品截图 / 安装体验
一套产品级Web端IM系统。
详细介绍 / 产品截图 / 演示视频
一套纯血鸿蒙NEXT产品级IM系统。
详细介绍 / 产品截图 / 安装
引用此评论
引用:JackJiang 发表于 2023-03-20 17:51 没让你开啊,谁让你开的
引用:zcy 发表于 2023-03-20 17:47 还有个疑问大佬,我开启了跨服桥接器,但是没有B2B的实际业务,只存在C2S S2C这两种模式,为什么会有信息 ...
引用:JackJiang 发表于 2023-03-20 16:24 完成跟MobileIMSDK-Web的互通
引用:zcy 发表于 2023-03-20 13:53 感谢大佬分享,跨服桥接器是为了完成什么任务
引用:139yu 发表于 2022-09-13 15:48 jdk使用的是java11嘛
引用:jungle1992 发表于 2022-01-22 17:36 原来如此,按照你的demo 可以运行起来了,打算试一下您提供的现成的client demo,感谢楼主,感谢52IM:lo ...
引用:JackJiang 发表于 2022-01-22 11:31 这种完整的通信框架肯定不是你用hello world的方法能测试的好的。 因为对于原始的tcp通信,框架它本身 ...
引用:jungle1992 发表于 2022-01-22 10:34 我下载的server的demo 并且跑起来了 但是我用调试助手连接的时候,出现这个问题,请问楼主这是啥呢?
WX20220122-112748@2x.png (251.48 KB, 下载次数: 6558)
4 年前 上传
000000587b22627269646765223a66616c73652c2274797065223a352c2264617461436f6e74656e74223a2241222c2266726f6d223a22616161222c22746f223a2230222c22516f53223a66616c73652c227479706575223a2d317d
测试工具(停止时).png (41.35 KB, 下载次数: 6380)
测试工具(定时发送时).png (51.18 KB, 下载次数: 6308)
1.jpg (403.35 KB, 下载次数: 6528)
引用:派大星先生 发表于 2020-08-12 11:10 我不知道怎么让ssm项目启动完成后,调用服务端ServerLauncherImpl类
引用:JackJiang 发表于 2020-08-12 10:35 报什么错?
引用:派大星先生 发表于 2020-08-12 07:59 ssm项目怎么启动后启动im服务啊,一直报错
引用:小小搬码工 发表于 2019-02-26 16:57 那谢谢,我了解,确实跨集群实现比较麻烦,你发的报告跨国的单一架构的虽然有时有些延迟,只要不要太大就 ...
引用:JackJiang 发表于 2019-02-26 16:38 其实mobileimsdk设计的时候就考虑了跨国运营,你可以看看这个运营过的产品数据:http://www.52im.net/thr ...
引用:小小搬码工 发表于 2019-02-26 16:36 其实主要应用的范围比较广,就是差不多是全球的,一台服务器有些范围覆盖不到,通信会差,所以打算在不同 ...
精华主题数超过100个。
积极发起、参与各类话题的讨论等,主题、发帖内容较有价值。
连续任职达1年以上的合格正式版主
为论区做出突出贡献的开发者、版主等。
Copyright © 2014-2026 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.145514 second(s), 43 queries , Gzip On.