diff --git a/jim-client/pom.xml b/jim-client/pom.xml
index 89bdb91..657683b 100644
--- a/jim-client/pom.xml
+++ b/jim-client/pom.xml
@@ -6,7 +6,7 @@
org.j-im
jim-parent
- 2.6.0.v20190114-RELEASE
+ 3.0.0.v20200101-RELEASE
../jim-parent/pom.xml
diff --git a/jim-client/src/main/java/org/jim/client/HelloClientAioHandler.java b/jim-client/src/main/java/org/jim/client/HelloClientAioHandler.java
index 046a4dd..d4483ff 100644
--- a/jim-client/src/main/java/org/jim/client/HelloClientAioHandler.java
+++ b/jim-client/src/main/java/org/jim/client/HelloClientAioHandler.java
@@ -3,11 +3,10 @@ package org.jim.client;
import java.nio.ByteBuffer;
import org.jim.common.ImConst;
-import org.jim.common.Protocol;
import org.tio.client.intf.ClientAioHandler;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
-import org.tio.core.exception.AioDecodeException;
+import org.tio.core.exception.ImDecodeException;
import org.tio.core.intf.AioHandler;
import org.tio.core.intf.Packet;
import org.jim.common.packets.Command;
@@ -52,7 +51,7 @@ public class HelloClientAioHandler implements AioHandler,ClientAioHandler
}
@Override
- public TcpPacket decode(ByteBuffer buffer,int limit, int position, int readableLength,ChannelContext channelContext) throws AioDecodeException {
+ public TcpPacket decode(ByteBuffer buffer,int limit, int position, int readableLength,ChannelContext channelContext) throws ImDecodeException {
TcpPacket tcpPacket = TcpServerDecoder.decode(buffer, channelContext);
return tcpPacket;
}
diff --git a/jim-client/src/main/java/org/jim/client/HelloClientStarter.java b/jim-client/src/main/java/org/jim/client/HelloClientStarter.java
index 06e082b..e7d79fb 100644
--- a/jim-client/src/main/java/org/jim/client/HelloClientStarter.java
+++ b/jim-client/src/main/java/org/jim/client/HelloClientStarter.java
@@ -1,7 +1,7 @@
package org.jim.client;
import org.jim.common.ImConst;
-import org.jim.common.ImAio;
+import org.jim.common.Jim;
import org.jim.common.packets.ChatBody;
import org.jim.common.packets.Command;
import org.jim.common.packets.LoginReqBody;
@@ -63,7 +63,7 @@ public class HelloClientStarter {
byte[] loginBody = new LoginReqBody("hello_client","123").toByte();
TcpPacket loginPacket = new TcpPacket(Command.COMMAND_LOGIN_REQ,loginBody);
//先登录;
- ImAio.send(clientChannelContext, loginPacket);
+ Jim.send(clientChannelContext, loginPacket);
ChatBody chatBody = ChatBody.newBuilder()
.setFrom("hello_client")
.setTo("admin")
@@ -72,6 +72,6 @@ public class HelloClientStarter {
.setGroup_id("100")
.setContent("Socket普通客户端消息测试!").build();
TcpPacket chatPacket = new TcpPacket(Command.COMMAND_CHAT_REQ,chatBody.toByte());
- ImAio.send(clientChannelContext, chatPacket);
+ Jim.send(clientChannelContext, chatPacket);
}
}
diff --git a/jim-client/src/main/java/org/jim/client/ImClientConfig.java b/jim-client/src/main/java/org/jim/client/ImClientConfig.java
new file mode 100644
index 0000000..64e1fcf
--- /dev/null
+++ b/jim-client/src/main/java/org/jim/client/ImClientConfig.java
@@ -0,0 +1,25 @@
+package org.jim.client;
+
+import org.jim.common.ImHandler;
+import org.jim.common.config.ImConfig;
+import org.jim.common.listener.ImListener;
+
+/**
+ * @ClassName ImClientConfig
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/4 10:42
+ * @Version 1.0
+ **/
+public class ImClientConfig extends ImConfig {
+
+ @Override
+ public ImHandler getImHandler() {
+ return null;
+ }
+
+ @Override
+ public ImListener getImListener() {
+ return null;
+ }
+}
diff --git a/jim-common/pom.xml b/jim-common/pom.xml
index 76a9eeb..5a32358 100644
--- a/jim-common/pom.xml
+++ b/jim-common/pom.xml
@@ -7,7 +7,7 @@
org.j-im
jim-parent
- 2.6.0.v20190114-RELEASE
+ 3.0.0.v20200101-RELEASE
../jim-parent/pom.xml
@@ -76,6 +76,18 @@
net.oschina.j2cache
j2cache-core
+
+ cn.hutool
+ hutool-all
+
+
+ org.apache.commons
+ commons-collections4
+
+
+ com.google.guava
+ guava
+
diff --git a/jim-common/src/main/java/org/jim/common/ImAio.java b/jim-common/src/main/java/org/jim/common/ImAio.java
deleted file mode 100644
index 72fdbd6..0000000
--- a/jim-common/src/main/java/org/jim/common/ImAio.java
+++ /dev/null
@@ -1,478 +0,0 @@
-package org.jim.common;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.jim.common.cluster.ImCluster;
-import org.jim.common.config.DefaultImConfigBuilder;
-import org.jim.common.listener.ImBindListener;
-import org.jim.common.packets.Client;
-import org.jim.common.packets.User;
-import org.jim.common.utils.ImKit;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
-import org.tio.core.ChannelContext;
-import org.tio.core.ChannelContextFilter;
-import org.tio.core.GroupContext;
-import org.tio.utils.lock.SetWithLock;
-
-import java.util.*;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
-/**
- * 版本: [1.0]
- * 功能说明:
- * @author : WChao 创建时间: 2017年9月22日 上午9:07:18
- */
-public class ImAio {
-
- public static ImConfig imConfig = null;
-
- private static Logger log = LoggerFactory.getLogger(ImAio.class);
- /**
- * 功能描述:[根据用户ID获取当前用户]
- * @author:WChao 创建时间: 2017年9月18日 下午4:34:39
- * @param userId
- * @return
- */
- public static User getUser(String userId){
- SetWithLock userChannelContexts = ImAio.getChannelContextsByUserId(userId);
- if(Objects.isNull(userChannelContexts)) {
- return null;
- }
- ReadLock readLock = userChannelContexts.getLock().readLock();
- readLock.lock();
- try{
- Set userChannels = userChannelContexts.getObj();
- if(CollectionUtils.isEmpty(userChannels)) {
- return null;
- }
- User user = null;
- for(ChannelContext channelContext : userChannels){
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- Client client = imSessionContext.getClient();
- user = client.getUser();
- if(user != null){
- return user;
- }
- }
- return user;
- }finally {
- readLock.unlock();
- }
- }
- /**
- * 功能描述:[根据用户ID获取当前用户所在通道集合]
- * @author:WChao 创建时间: 2017年9月18日 下午4:34:39
- * @param userId
- * @return
- */
- public static SetWithLock getChannelContextsByUserId(String userId){
- SetWithLock channelContexts = Aio.getChannelContextsByUserid(imConfig.getGroupContext(), userId);
- return channelContexts;
- }
- /**
- * 功能描述:[获取所有用户(在线+离线)]
- * @author:WChao 创建时间: 2017年9月18日 下午4:31:54
- * @return
- */
- public static List getAllUser(){
- List users = new ArrayList();
- SetWithLock allChannels = Aio.getAllChannelContexts(imConfig.getGroupContext());
- if(allChannels == null) {
- return users;
- }
- ReadLock readLock = allChannels.getLock().readLock();
- readLock.lock();
- try{
- Set userChannels = allChannels.getObj();
- if(CollectionUtils.isEmpty(userChannels)) {
- return users;
- }
- for(ChannelContext channelContext : userChannels){
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- Client client = imSessionContext.getClient();
- if(client != null && client.getUser() != null){
- User user = ImKit.copyUserWithoutUsers(client.getUser());
- users.add(user);
- }
- }
- }finally {
- readLock.unlock();
- }
- return users;
- }
- /**
- * 功能描述:[获取所有在线用户]
- * @author:WChao 创建时间: 2017年9月18日 下午4:31:42
- * @return
- */
- public static List getAllOnlineUser(){
- List users = new ArrayList();
- SetWithLock onlineChannels = Aio.getAllConnectedsChannelContexts(imConfig.getGroupContext());
- if(onlineChannels == null) {
- return users;
- }
- ReadLock readLock = onlineChannels.getLock().readLock();
- readLock.lock();
- try{
- Set userChannels = onlineChannels.getObj();
- for(ChannelContext channelContext : userChannels){
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- if(imSessionContext != null){
- Client client = imSessionContext.getClient();
- if(client != null && client.getUser() != null){
- User user = ImKit.copyUserWithoutUsers(client.getUser());
- users.add(user);
- }
- }
- }
- }finally {
- readLock.unlock();
- }
- return users;
- }
- /**
- * 根据群组获取所有用户;
- * @param group
- * @return
- */
- public static List getAllUserByGroup(String group){
- SetWithLock withLockChannels = Aio.getChannelContextsByGroup(imConfig.getGroupContext(), group);
- if(withLockChannels == null){
- return null;
- }
- ReadLock readLock = withLockChannels.getLock().readLock();
- readLock.lock();
- try{
- Set channels = withLockChannels.getObj();
- if(CollectionUtils.isEmpty(channels)){
- return null;
- }
- List users = new ArrayList();
- Map userMaps = new HashMap();
- for(ChannelContext channelContext : channels){
- String userId = channelContext.getUserid();
- User user = getUser(userId);
- if(user != null && userMaps.get(userId) == null){
- userMaps.put(userId, user);
- users.add(user);
- }
- }
- userMaps = null;
- return users;
- }finally{
- readLock.unlock();
- }
- }
- /**
- * 功能描述:[发送到群组(所有不同协议端)]
- * @author:WChao 创建时间: 2017年9月21日 下午3:26:57
- * @param group
- * @param packet
- */
- public static void sendToGroup(String group, ImPacket packet){
- if(packet.getBody() == null) {
- return;
- }
- SetWithLock withLockChannels = Aio.getChannelContextsByGroup(imConfig.getGroupContext(), group);
- if(withLockChannels == null){
- ImCluster cluster = imConfig.getCluster();
- if (cluster != null && !packet.isFromCluster()) {
- cluster.clusterToGroup(imConfig.getGroupContext(), group, packet);
- }
- return;
- }
- ReadLock readLock = withLockChannels.getLock().readLock();
- readLock.lock();
- try{
- Set channels = withLockChannels.getObj();
- if(CollectionUtils.isNotEmpty(channels)){
- for(ChannelContext channelContext : channels){
- send(channelContext,packet);
- }
- }
- }finally{
- readLock.unlock();
- ImCluster cluster = imConfig.getCluster();
- if (cluster != null && !packet.isFromCluster()) {
- cluster.clusterToGroup(imConfig.getGroupContext(), group, packet);
- }
- }
- }
- /**
- * 发送到指定通道;
- * @param channelContext
- * @param packet
- */
- public static boolean send(ChannelContext channelContext,ImPacket packet){
- ImPacket respPacket = initAndSetConvertPacket(channelContext , packet);
- if(respPacket == null){
- return false;
- }
- return Aio.send(channelContext,respPacket);
- }
-
- /**
- * 阻塞发送(确认把packet发送到对端后再返回)
- * @param channelContext
- * @param packet
- * @return
- */
- public static boolean bSend(ChannelContext channelContext , ImPacket packet){
- ImPacket respPacket = initAndSetConvertPacket(channelContext , packet);
- if(respPacket == null){
- return false;
- }
- return Aio.bSend(channelContext,respPacket);
- }
- /**
- * 发送到指定用户;
- * @param userId
- * @param packet
- */
- public static void sendToUser(String userId,ImPacket packet){
- if(StringUtils.isEmpty(userId)) {
- return;
- }
- SetWithLock toChannelContexts = getChannelContextsByUserId(userId);
- if(toChannelContexts == null || toChannelContexts.size() < 1){
- ImCluster cluster = imConfig.getCluster();
- if (cluster != null && !packet.isFromCluster()) {
- cluster.clusterToUser(imConfig.getGroupContext(), userId, packet);
- }
- return;
- }
- ReadLock readLock = toChannelContexts.getLock().readLock();
- readLock.lock();
- try{
- Set channels = toChannelContexts.getObj();
- for(ChannelContext channelContext : channels){
- send(channelContext, packet);
- }
- }finally{
- readLock.unlock();
- ImCluster cluster = imConfig.getCluster();
- if (cluster != null && !packet.isFromCluster()) {
- cluster.clusterToUser(imConfig.getGroupContext(), userId, packet);
- }
- }
- }
- /**
- * 发送到指定ip对应的集合
- * @param groupContext
- * @param ip
- * @param packet
- */
- public static void sendToIp(GroupContext groupContext, String ip, ImPacket packet) {
- sendToIp(groupContext, ip, packet, null);
- }
-
- public static void sendToIp(GroupContext groupContext, String ip, ImPacket packet, ChannelContextFilter channelContextFilter) {
- sendToIp(groupContext, ip, packet, channelContextFilter, false);
- }
-
- private static Boolean sendToIp(GroupContext groupContext, String ip, ImPacket packet, ChannelContextFilter channelContextFilter, boolean isBlock) {
- try{
- SetWithLock setWithLock = groupContext.ips.clients(groupContext, ip);
- if (setWithLock == null) {
- log.info("{}, 没有ip为[{}]的对端", groupContext.getName(), ip);
- return false;
- } else {
- Boolean ret = sendToSet(groupContext, setWithLock, packet, channelContextFilter, isBlock);
- return ret;
- }
- }finally{
- ImCluster cluster = imConfig.getCluster();
- if (cluster != null && !packet.isFromCluster()) {
- cluster.clusterToIp(groupContext, ip, packet);
- }
- }
- }
-
- public static Boolean sendToSet(GroupContext groupContext, SetWithLock setWithLock, ImPacket packet, ChannelContextFilter channelContextFilter, boolean isBlock){
- Lock lock = setWithLock.getLock().readLock();
- lock.lock();
- try {
- Set sets = (Set) setWithLock.getObj();
- for (ChannelContext channelContext : sets) {
- SetWithLock convertSet = new SetWithLock(new HashSet());
- convertSet.add(channelContext);
- ImPacket resPacket = ImKit.ConvertRespPacket(packet, packet.getCommand(), channelContext);
- Aio.sendToSet(groupContext, convertSet, resPacket, channelContextFilter);
- }
- }finally {
- lock.unlock();
- }
- return true;
- }
- /**
- * 转换协议包同时设置Packet包信息;
- * @param channelContext
- * @param packet
- * @return
- */
- private static ImPacket initAndSetConvertPacket(ChannelContext channelContext , ImPacket packet){
- if(channelContext == null) {
- return null;
- }
- ImPacket respPacket = ImKit.ConvertRespPacket(packet,packet.getCommand(),channelContext);
- if(respPacket == null){
- log.error("转换协议包为空,请检查协议!");
- return null;
- }
- respPacket.setSynSeq(packet.getSynSeq());
- if(imConfig == null){
- imConfig = new DefaultImConfigBuilder().setGroupContext(channelContext.getGroupContext()).build();
- }
- return respPacket;
- }
- /**
- * 绑定用户;
- * @param channelContext
- * @param userId
- */
- public static void bindUser(ChannelContext channelContext,String userId){
- bindUser(channelContext, userId,null);
- }
- /**
- * 绑定用户,同时可传递监听器执行回调函数
- * @param channelContext
- * @param userId
- * @param bindListener(绑定监听器回调)
- */
- public static void bindUser(ChannelContext channelContext,String userId,ImBindListener bindListener){
- Aio.bindUser(channelContext, userId);
- if(bindListener != null){
- try {
- bindListener.onAfterUserBind(channelContext, userId);
- } catch (Exception e) {
- log.error(e.toString(),e);
- }
- }
- }
- /**
- * 解绑用户
- * @param userId
- */
- public static void unbindUser(String userId){
- unbindUser(userId, null);
- }
- /**
- * 解除绑定用户,同时可传递监听器执行回调函数
- * @param userId
- * @param bindListener(解绑定监听器回调)
- */
- public static void unbindUser(String userId,ImBindListener bindListener){
- Aio.unbindUser(imConfig.getGroupContext(), userId);
- if(bindListener != null){
- try {
- SetWithLock userChannelContexts = ImAio.getChannelContextsByUserId(userId);
- if(userChannelContexts == null || userChannelContexts.size() == 0) {
- return;
- }
- ReadLock readLock = userChannelContexts.getLock().readLock();
- readLock.lock();
- try{
- Set channels = userChannelContexts.getObj();
- for(ChannelContext channelContext : channels){
- bindListener.onAfterUserBind(channelContext, userId);
- }
- }finally{
- readLock.unlock();
- }
- } catch (Exception e) {
- log.error(e.toString(),e);
- }
- }
- }
- /**
- * 绑定群组;
- * @param channelContext
- * @param group
- */
- public static void bindGroup(ChannelContext channelContext,String group){
- bindGroup(channelContext, group,null);
- }
- /**
- * 绑定群组,同时可传递监听器执行回调函数
- * @param channelContext
- * @param group
- * @param bindListener(绑定监听器回调)
- */
- public static void bindGroup(ChannelContext channelContext,String group,ImBindListener bindListener){
- Aio.bindGroup(channelContext, group);
- if(bindListener != null){
- try {
- bindListener.onAfterGroupBind(channelContext, group);
- } catch (Exception e) {
- log.error(e.toString(),e);
- }
- }
- }
- /**
- * 与指定群组解除绑定
- * @param userId
- * @param group
- */
- public static void unbindGroup(String userId,String group){
- unbindGroup(userId, group, null);
- }
- /**
- * 与指定群组解除绑定,同时可传递监听器执行回调函数
- * @param userId
- * @param group
- * @param bindListener(解绑定监听器回调)
- */
- public static void unbindGroup(String userId,String group,ImBindListener bindListener){
- SetWithLock userChannelContexts = ImAio.getChannelContextsByUserId(userId);
- if(userChannelContexts == null || userChannelContexts.size() == 0) {
- return;
- }
- ReadLock readLock = userChannelContexts.getLock().readLock();
- readLock.lock();
- try{
- Set channels = userChannelContexts.getObj();
- for(ChannelContext channelContext : channels){
- Aio.unbindGroup(group, channelContext);
- if(bindListener != null){
- try {
- bindListener.onAfterGroupUnbind(channelContext, group);
- } catch (Exception e) {
- log.error(e.toString(),e);
- }
- }
- }
- }finally{
- readLock.unlock();
- }
- }
- /**
- * 移除用户, 和close方法一样,只不过不再进行重连等维护性的操作
- * @param userId
- * @param remark
- */
- public static void remove(String userId,String remark){
- SetWithLock userChannelContexts = getChannelContextsByUserId(userId);
- if(userChannelContexts != null && userChannelContexts.size() > 0){
- ReadLock readLock = userChannelContexts.getLock().readLock();
- readLock.lock();
- try{
- Set channels = userChannelContexts.getObj();
- for(ChannelContext channelContext : channels){
- remove(channelContext, remark);
- }
- }finally{
- readLock.unlock();
- }
- }
- }
- /**
- * 移除指定channel, 和close方法一样,只不过不再进行重连等维护性的操作
- * @param channelContext
- * @param remark
- */
- public static void remove(ChannelContext channelContext,String remark){
- Aio.remove(channelContext, remark);
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/ImChannelContext.java b/jim-common/src/main/java/org/jim/common/ImChannelContext.java
new file mode 100644
index 0000000..a6b47a8
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/ImChannelContext.java
@@ -0,0 +1,68 @@
+package org.jim.common;
+
+import org.jim.common.config.ImConfig;
+import org.jim.common.protocol.IProtocol;
+import org.tio.core.ChannelContext;
+import org.tio.core.Node;
+import org.tio.utils.prop.MapWithLockPropSupport;
+import org.tio.utils.thread.pool.AbstractQueueRunnable;
+
+/**
+ * @ClassName ImChannelContext
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/5 23:40
+ * @Version 1.0
+ **/
+public abstract class ImChannelContext extends MapWithLockPropSupport implements ImConst{
+
+ protected ImConfig imConfig;
+
+ protected ChannelContext tioChannelContext;
+
+ public ImChannelContext(ImConfig imConfig, ChannelContext tioChannelContext) {
+ this.imConfig = imConfig;
+ this.tioChannelContext = tioChannelContext;
+ }
+
+ public ImConfig getImConfig() {
+ return imConfig;
+ }
+
+ public void setImConfig(ImConfig imConfig) {
+ this.imConfig = imConfig;
+ }
+
+ public void setSessionContext(ImSessionContext imSessionContext){
+ this.setAttribute(Key.IM_CHANNEL_SESSION_CONTEXT_KEY, imSessionContext);
+ }
+
+ public ImSessionContext getSessionContext(){
+ return (ImSessionContext)this.getAttribute(Key.IM_CHANNEL_SESSION_CONTEXT_KEY);
+ }
+
+ public String getId() {
+ return tioChannelContext.getId();
+ }
+
+ public Node getClientNode(){
+ return tioChannelContext.getClientNode();
+ }
+
+ public void setPacketNeededLength(Integer packetNeededLength) {
+ this.tioChannelContext.setPacketNeededLength(packetNeededLength);
+ }
+
+ public String getUserId(){
+ return tioChannelContext.userid;
+ }
+
+ public void setUserId(String userId){
+ tioChannelContext.setUserid(userId);
+ }
+
+ public ChannelContext getTioChannelContext() {
+ return tioChannelContext;
+ }
+
+}
diff --git a/jim-common/src/main/java/org/jim/common/ImClientGroupContext.java b/jim-common/src/main/java/org/jim/common/ImClientGroupContext.java
deleted file mode 100644
index 0a17fa2..0000000
--- a/jim-common/src/main/java/org/jim/common/ImClientGroupContext.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- *
- */
-package org.jim.common;
-
-import java.util.concurrent.ThreadPoolExecutor;
-
-import org.tio.client.ClientGroupContext;
-import org.tio.client.ReconnConf;
-import org.tio.client.intf.ClientAioHandler;
-import org.tio.client.intf.ClientAioListener;
-import org.tio.utils.thread.pool.SynThreadPoolExecutor;
-
-/**
- * @author WChao
- *
- */
-public class ImClientGroupContext extends ClientGroupContext{
-
- public ImClientGroupContext(ClientAioHandler aioHandler,ClientAioListener aioListener) {
- super(aioHandler, aioListener);
- }
-
- public ImClientGroupContext(ClientAioHandler aioHandler,ClientAioListener aioListener, ReconnConf reconnConf,SynThreadPoolExecutor tioExecutor, ThreadPoolExecutor groupExecutor) {
- super(aioHandler, aioListener, reconnConf, tioExecutor, groupExecutor);
- }
-
- public ImClientGroupContext(ClientAioHandler aioHandler,ClientAioListener aioListener, ReconnConf reconnConf) {
- super(aioHandler, aioListener, reconnConf);
- }
-
-}
diff --git a/jim-common/src/main/java/org/jim/common/ImConfig.java b/jim-common/src/main/java/org/jim/common/ImConfig.java
deleted file mode 100644
index 4a5b593..0000000
--- a/jim-common/src/main/java/org/jim/common/ImConfig.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *
- */
-package org.jim.common;
-
-import org.jim.common.config.Config;
-import org.jim.common.http.HttpConfig;
-import org.jim.common.ws.WsServerConfig;
-/**
- * @author WChao
- *
- */
-public class ImConfig extends Config{
-
- /**
- * http相关配置;
- */
- private HttpConfig httpConfig;
- /**
- * WebSocket相关配置;
- */
- private WsServerConfig wsServerConfig;
-
- public ImConfig() {
- this.httpConfig = new HttpConfig();
- this.wsServerConfig = new WsServerConfig();
- }
-
- public ImConfig(String bindIp,Integer bindPort){
- this.bindIp = bindIp;
- this.bindPort = bindPort;
- this.httpConfig = new HttpConfig();
- this.wsServerConfig = new WsServerConfig();
- }
-
- public HttpConfig getHttpConfig() {
- return httpConfig;
- }
-
- public void setHttpConfig(HttpConfig httpConfig) {
- this.httpConfig = httpConfig;
- }
-
- public WsServerConfig getWsServerConfig() {
- return wsServerConfig;
- }
-
- public void setWsServerConfig(WsServerConfig wsServerConfig) {
- this.wsServerConfig = wsServerConfig;
- }
-
-}
diff --git a/jim-common/src/main/java/org/jim/common/ImConst.java b/jim-common/src/main/java/org/jim/common/ImConst.java
index b37c3fa..7af33b8 100644
--- a/jim-common/src/main/java/org/jim/common/ImConst.java
+++ b/jim-common/src/main/java/org/jim/common/ImConst.java
@@ -7,52 +7,296 @@ package org.jim.common;
*/
public interface ImConst
{
- public static final String AUTH_KEY = "authKey";
-
- public static final int SERVER_PORT = 8888;
-
- public static final String CHARSET = "utf-8";
-
- public static final String TO = "to";
-
- public static final String CHANNEL = "channel";
-
- public static final String PACKET = "packet";
-
- public static final String STATUS = "status";
-
- public static final String HTTP_REQUEST = "httpRequest";
- public static final String CHAT_QUEUE = "chat_queue";
-
- public static final String STORE = "store";
-
- public static final String PUSH = "push";
-
- public static final String CHAT = "chat";
-
- public static final String GROUP = "group";
-
- public static final String USER = "user";
-
- public static final String TERMINAL = "terminal";
-
- public static final String INFO = "info";
-
- public static final String FRIENDS = "friends";
-
- public static final String ONLINE = "online";
-
- public static final String OFFLINE = "offline";
-
- public static final String ON = "on";
-
- public static final String OFF = "off";
-
- public static final String JIM = "JIM";
-
- public static final String CONVERTER = "converter";
+ interface Key{
+ String IM_CHANNEL_CONTEXT_KEY = "im_channel_context_key";
+ String IM_CHANNEL_SESSION_CONTEXT_KEY = "im_channel_session_context_key";
+ /**
+ * 存放HttpConfig
+ */
+ String HTTP_SERVER_CONFIG = "JIM_HTTP_SERVER_CONFIG";
+ }
- public static final String BASE_ASYNC_CHAT_MESSAGE_PROCESSOR = "base_async_chat_message_processor";
+ interface Topic{
+ String REDIS_CLUSTER_TOPIC_SUFFIX = "REDIS_";
+ String JIM_CLUSTER_TOPIC = "JIM_CLUSTER";
+ }
+
+ interface Protocol{
+ /**
+ * 心跳字节
+ */
+ byte HEARTBEAT_BYTE = -128;
+
+ /**
+ * 握手字节
+ */
+ byte HANDSHAKE_BYTE = -127;
+
+ /**
+ * 协议版本号
+ */
+ byte VERSION = 0x01;
+
+ String WEB_SOCKET = "ws";
+
+ String HTTP = "http";
+
+ String TCP = "tcp";
+
+ String COOKIE_NAME_FOR_SESSION = "jim-s";
+ /**
+ * 消息体最多为多少,只支持多少M数据
+ */
+ int MAX_LENGTH_OF_BODY = (int) (1024 * 1024 * 2.1);
+
+ /**
+ * 消息头最少为多少个字节,1+1+2+(2+4)
+ */
+ int LEAST_HEADER_LENGTH = 4;
+
+ /**
+ * 加密标识位mask,1为加密,否则不加密
+ */
+ byte FIRST_BYTE_MASK_ENCRYPT = -128;
+
+ /**
+ * 压缩标识位mask,1为压缩,否则不压缩
+ */
+ byte FIRST_BYTE_MASK_COMPRESS = 0B01000000;
+
+ /**
+ * 是否有同步序列号标识位mask,如果有同步序列号,则消息头会带有同步序列号,否则不带
+ */
+ byte FIRST_BYTE_MASK_HAS_SYNSEQ = 0B00100000;
+
+ /**
+ * 是否是用4字节来表示消息体的长度
+ */
+ byte FIRST_BYTE_MASK_4_BYTE_LENGTH = 0B00010000;
+
+ /**
+ * 版本号mask
+ */
+ byte FIRST_BYTE_MASK_VERSION = 0B00001111;
+ }
+
+ interface Http{
+ /**
+ * 请求体的格式
+ * @author wchao
+ * 2017年6月28日 上午10:03:12
+ */
+ enum RequestBodyFormat {
+ URLENCODED, MULTIPART, TEXT
+ }
+
+ /**
+ *Accept-Language : zh-CN,zh;q=0.8
+ Sec-WebSocket-Version : 13
+ Sec-WebSocket-Extensions : permessage-deflate; client_max_window_bits
+ Upgrade : websocket
+ Host : t-io.org:9321
+ Accept-Encoding : gzip, deflate, sdch
+ User-Agent : Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
+ Origin : http://www.t-io.org:9292
+ Sec-WebSocket-Key : kmCL2C7q9vtNSMyHpft7lw==
+ Connection : Upgrade
+ Cache-Control : no-cache
+ Pragma : no-cache
+ * @author wchao
+ * 2017年5月27日 下午2:11:57
+ */
+ interface RequestHeaderKey {
+ String Cookie = "Cookie".toLowerCase();//Cookie: $Version=1; Skin=new;
+ String Origin = "Origin".toLowerCase(); //http://127.0.0.1
+ String Sec_WebSocket_Key = "Sec-WebSocket-Key".toLowerCase(); //2GFwqJ1Z37glm62YKKLUeA==
+ String Cache_Control = "Cache-Control".toLowerCase(); //no-cache
+ String Connection = "Connection".toLowerCase(); //Upgrade, keep-alive
+ String User_Agent = "User-Agent".toLowerCase(); //Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3088.3 Safari/537.36
+ String Sec_WebSocket_Version = "Sec-WebSocket-Version".toLowerCase(); //13
+ String Host = "Host".toLowerCase(); //127.0.0.1:9321
+ String Pragma = "Pragma".toLowerCase(); //no-cache
+ String Accept_Encoding = "Accept-Encoding".toLowerCase(); //gzip, deflate, br
+ String Accept_Language = "Accept-Language".toLowerCase(); //zh-CN,zh;q=0.8,en;q=0.6
+ String Upgrade = "Upgrade".toLowerCase(); //websocket
+ String Sec_WebSocket_Extensions = "Sec-WebSocket-Extensions".toLowerCase(); //permessage-deflate; client_max_window_bits
+ String Content_Length = "Content-Length".toLowerCase(); //65
+ String Content_Type = "Content-Type".toLowerCase();// : 【application/x-www-form-urlencoded】【application/x-www-form-urlencoded; charset=UTF-8】【multipart/form-data; boundary=----WebKitFormBoundaryuwYcfA2AIgxqIxA0 】
+ String If_Modified_Since = "If-Modified-Since".toLowerCase(); //与Last-Modified配合
+ /**
+ * 值为XMLHttpRequest则为Ajax
+ */
+ String X_Requested_With = "X-Requested-With".toLowerCase();//XMLHttpRequest
+ }
+
+ /**
+ *
+ * @author wchao
+ * 2017年6月27日 下午8:23:58
+ */
+ interface RequestHeaderValue {
+ interface Connection {
+ String keep_alive = "keep-alive".toLowerCase();
+ String Upgrade = "Upgrade".toLowerCase();
+ String close = "close".toLowerCase();
+ }
+
+ //application/x-www-form-urlencoded、multipart/form-data、text/plain
+ interface Content_Type {
+ /**
+ * 普通文本,一般会是json或是xml
+ */
+ String text_plain = "text/plain".toLowerCase();
+ /**
+ * 文件上传
+ */
+ String multipart_form_data = "multipart/form-data".toLowerCase();
+ /**
+ * 普通的key-value
+ */
+ String application_x_www_form_urlencoded = "application/x-www-form-urlencoded".toLowerCase();
+ }
+ }
+
+ interface ResponseHeaderKey {
+ String Set_Cookie = "Set-Cookie".toLowerCase(); //Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
+ String Content_Length = "Content-Length".toLowerCase(); //65
+
+ String Connection = "Connection".toLowerCase(); //Upgrade, keep-alive
+ String Keep_Alive = "Keep-Alive".toLowerCase(); //Keep-Alive:timeout=20
+ String Sec_WebSocket_Accept = "Sec-WebSocket-Accept".toLowerCase();
+ String Upgrade = "Upgrade".toLowerCase();
+
+ /**
+ * Content-Disposition: attachment;filename=FileName.txt
+ * 文件下载
+ */
+ String Content_disposition = "Content-disposition".toLowerCase();
+ /**
+ * 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。
+ * 利用gzip压缩文档能够显著地减少HTML文档的下载时间。
+ * Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。
+ * 因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,
+ * 为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
+ */
+ String Content_Encoding = "Content-Encoding".toLowerCase();
+ /**
+ * 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。
+ * 由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
+ */
+ String Content_Type = "Content-Type".toLowerCase();
+ /**
+ * 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
+ */
+ String Date = "Date".toLowerCase();
+ /**
+ * 应该在什么时候认为文档已经过期,从而不再缓存它?
+ */
+ String Expires = "Expires".toLowerCase();
+ /**
+ * 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,
+ * 只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
+ */
+ String Last_Modified = "Last-Modified".toLowerCase();
+ /**
+ * 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
+ */
+ String Location = "Location".toLowerCase();
+ /**
+ * 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。
+ 注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。
+
+ 注意Refresh的意义是"N秒之后刷新本页面或访问指定页面",而不是"每隔N秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。
+
+ 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
+ */
+ String Refresh = "Refresh".toLowerCase();
+ /**
+ * 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
+ */
+ String Server = "Server".toLowerCase();
+
+ /**
+ *
+ */
+ String Access_Control_Allow_Origin = "Access-Control-Allow-Origin".toLowerCase(); //value: *
+
+ /**
+ *
+ */
+ String Access_Control_Allow_Headers = "Access-Control-Allow-Headers".toLowerCase(); //value: x-requested-with,content-type
+
+ /**
+ * 是否是从缓存中获取的数据,tio-httpserver特有的头部信息
+ */
+ String tio_from_cache = "tio-from-cache";
+ }
+
+ /**
+ *
+ * @author wchao
+ * 2017年6月27日 下午8:24:02
+ */
+ interface ResponseHeaderValue {
+ interface Connection {
+ String keep_alive = "keep-alive".toLowerCase();
+ String Upgrade = "Upgrade".toLowerCase();
+ String close = "close".toLowerCase();
+ }
+ }
+
+ /**
+ *
+ */
+ String SERVER_INFO = "jim-http-server/0.0.1";
+
+ /**
+ * 默认规定连接到本服务器的客户端统一用utf-8
+ */
+ String CHARSET_NAME = "utf-8";
+ }
+
+ String AUTH_KEY = "authKey";
+
+ int SERVER_PORT = 8888;
+
+ String CHARSET = "utf-8";
+
+ String TO = "to";
+
+ String CHANNEL = "channel";
+
+ String PACKET = "packet";
+
+ String STATUS = "status";
+
+ String HTTP_REQUEST = "httpRequest";
+
+ String STORE = "store";
+
+ String PUSH = "push";
+
+ String CHAT = "chat";
+
+ String GROUP = "group";
+
+ String USER = "user";
+
+ String TERMINAL = "terminal";
+
+ String INFO = "info";
+
+ String FRIENDS = "friends";
+
+ String ONLINE = "online";
+
+ String OFFLINE = "offline";
+
+ String JIM = "JIM";
+
+ String CONVERTER = "converter";
+
+ String BASE_ASYNC_CHAT_MESSAGE_PROCESSOR = "base_async_chat_message_processor";
}
diff --git a/jim-common/src/main/java/org/jim/common/ImDecoder.java b/jim-common/src/main/java/org/jim/common/ImDecoder.java
index 78a018d..46d5a27 100644
--- a/jim-common/src/main/java/org/jim/common/ImDecoder.java
+++ b/jim-common/src/main/java/org/jim/common/ImDecoder.java
@@ -5,10 +5,8 @@ package org.jim.common;
import java.nio.ByteBuffer;
+import org.jim.common.exception.ImDecodeException;
import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
-
-
/**
* 版本: [1.0]
* 功能说明:
@@ -16,5 +14,5 @@ import org.tio.core.exception.AioDecodeException;
*/
public interface ImDecoder {
- public ImPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException;
+ public ImPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws ImDecodeException;
}
diff --git a/jim-common/src/main/java/org/jim/common/ImHandler.java b/jim-common/src/main/java/org/jim/common/ImHandler.java
new file mode 100644
index 0000000..4698b55
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/ImHandler.java
@@ -0,0 +1,47 @@
+package org.jim.common;
+
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.common.exception.ImException;
+import java.nio.ByteBuffer;
+
+/**
+ * @ClassName ImHandler
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/6 2:09
+ * @Version 1.0
+ **/
+public interface ImHandler {
+ /**
+ * 根据ByteBuffer解码成业务需要的Packet对象.
+ * 如果收到的数据不全,导致解码失败,请返回null,在下次消息来时框架层会自动续上前面的收到的数据
+ * @param buffer 参与本次希望解码的ByteBuffer
+ * @param limit ByteBuffer的limit
+ * @param position ByteBuffer的position,不一定是0哦
+ * @param readableLength ByteBuffer参与本次解码的有效数据(= limit - position)
+ * @param imChannelContext
+ * @return
+ * @throws ImDecodeException
+ */
+ ImPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ImChannelContext imChannelContext) throws ImDecodeException;
+
+ /**
+ * 编码
+ * @param imPacket
+ * @param imConfig
+ * @param imChannelContext
+ * @return
+ * @author: WChao
+ */
+ ByteBuffer encode(ImPacket imPacket, ImConfig imConfig, ImChannelContext imChannelContext);
+
+ /**
+ * 处理消息包
+ * @param imPacket
+ * @param imChannelContext
+ * @throws ImException
+ * @author: WChao
+ */
+ void handler(ImPacket imPacket, ImChannelContext imChannelContext) throws ImException;
+}
diff --git a/jim-common/src/main/java/org/jim/common/ImPacket.java b/jim-common/src/main/java/org/jim/common/ImPacket.java
index 66a2234..b6d3792 100644
--- a/jim-common/src/main/java/org/jim/common/ImPacket.java
+++ b/jim-common/src/main/java/org/jim/common/ImPacket.java
@@ -1,5 +1,6 @@
package org.jim.common;
+import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.jim.common.packets.Command;
@@ -8,7 +9,7 @@ import org.jim.common.packets.Command;
* @author WChao
*
*/
-public class ImPacket extends Packet
+public class ImPacket extends Packet implements ImConst
{
private static final long serialVersionUID = 2000118564569232098L;
/**
@@ -23,6 +24,8 @@ public class ImPacket extends Packet
* 消息命令;
*/
private Command command;
+
+ protected ImChannelContext imChannelContext;
public ImPacket(){}
@@ -109,7 +112,7 @@ public class ImPacket extends Packet
*/
public int calcHeaderLength(boolean is4byteLength)
{
- int ret = Protocol.LEAST_HEADER_LENGHT;
+ int ret = Protocol.LEAST_HEADER_LENGTH;
if (is4byteLength)
{
ret += 2;
@@ -165,4 +168,11 @@ public class ImPacket extends Packet
this.status = status;
}
+ public ImChannelContext getImChannelContext() {
+ return imChannelContext;
+ }
+
+ public void setImChannelContext(ImChannelContext imChannelContext) {
+ this.imChannelContext = imChannelContext;
+ }
}
diff --git a/jim-common/src/main/java/org/jim/common/ImSessionContext.java b/jim-common/src/main/java/org/jim/common/ImSessionContext.java
index 3ea9e03..435a1d1 100644
--- a/jim-common/src/main/java/org/jim/common/ImSessionContext.java
+++ b/jim-common/src/main/java/org/jim/common/ImSessionContext.java
@@ -2,15 +2,13 @@ package org.jim.common;
import org.jim.common.packets.Client;
import org.tio.monitor.RateLimiterWrap;
-import org.tio.server.intf.ServerAioHandler;
/**
*
* @author wchao
*
*/
-public class ImSessionContext extends SessionContext
-{
+public class ImSessionContext {
/**
* 消息请求频率控制器
*/
@@ -19,21 +17,19 @@ public class ImSessionContext extends SessionContext
protected Client client = null;
protected String token = null;
+
+ protected ImChannelContext imChannelContext;
+
+ protected String id;
+
/**
- * 通道所属协议处理器;
- */
- private ServerAioHandler protocolHandler;
-
- /**
- *
- *
- * @author: wchao
+ * @author: WChao
* 2017年2月21日 上午10:27:54
- *
*/
- public ImSessionContext()
- {
-
+ public ImSessionContext(){}
+
+ public ImSessionContext(ImChannelContext imChannelContext){
+ this.imChannelContext = imChannelContext;
}
/**
* @return the client
@@ -81,12 +77,19 @@ public class ImSessionContext extends SessionContext
this.requestRateLimiter = requestRateLimiter;
}
- public ServerAioHandler getProtocolHandler() {
- return protocolHandler;
+ public ImChannelContext getImChannelContext() {
+ return imChannelContext;
}
- public ImSessionContext setProtocolHandler(ServerAioHandler protocolHandler) {
- this.protocolHandler = protocolHandler;
- return this;
+ public void setImChannelContext(ImChannelContext imChannelContext) {
+ this.imChannelContext = imChannelContext;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
}
}
diff --git a/jim-common/src/main/java/org/jim/common/ImStatus.java b/jim-common/src/main/java/org/jim/common/ImStatus.java
index b818564..bb0802a 100644
--- a/jim-common/src/main/java/org/jim/common/ImStatus.java
+++ b/jim-common/src/main/java/org/jim/common/ImStatus.java
@@ -39,7 +39,7 @@ public enum ImStatus implements Status{
private String text;
- private ImStatus(int status, String description, String text) {
+ ImStatus(int status, String description, String text) {
this.status = status;
this.description = description;
this.text = text;
diff --git a/jim-common/src/main/java/org/jim/common/Jim.java b/jim-common/src/main/java/org/jim/common/Jim.java
new file mode 100644
index 0000000..2016ab6
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/Jim.java
@@ -0,0 +1,200 @@
+package org.jim.common;
+
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImException;
+import org.jim.common.listener.ImUserListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tio.core.Tio;
+import org.tio.core.ChannelContext;
+import org.tio.core.ChannelContextFilter;
+import org.tio.core.TioConfig;
+import org.tio.utils.lock.SetWithLock;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+/**
+ * 版本: [1.0]
+ * 功能说明:
+ * @author : WChao 创建时间: 2017年9月22日 上午9:07:18
+ */
+public class Jim {
+
+ public static ImConfig imConfig = ImConfig.Global.get();
+
+ private static Logger log = LoggerFactory.getLogger(Jim.class);
+
+ /**
+ * 功能描述:[发送到群组(所有不同协议端)]
+ * @author:WChao 创建时间: 2017年9月21日 下午3:26:57
+ * @param group
+ * @param packet
+ */
+ public static void sendToGroup(String group, ImPacket packet){
+ Tio.sendToGroup(imConfig.getTioConfig(), group, packet);
+ }
+ /**
+ * 发送到指定通道;
+ * @param channelContext
+ * @param imPacket
+ */
+ public static boolean send(ImChannelContext channelContext, ImPacket imPacket){
+ if(channelContext == null){
+ return false;
+ }
+ return Tio.send(channelContext.getTioChannelContext(),imPacket);
+ }
+
+ /**
+ * 阻塞发送(确认把packet发送到对端后再返回)
+ * @param channelContext
+ * @param packet
+ * @return
+ */
+ public static boolean bSend(ImChannelContext channelContext , ImPacket packet){
+ if(channelContext == null){
+ return false;
+ }
+ return Tio.bSend(channelContext.getTioChannelContext(), packet);
+ }
+ /**
+ * 发送到指定用户;
+ * @param userId
+ * @param packet
+ */
+ public static void sendToUser(String userId,ImPacket packet){
+ Tio.sendToUser(imConfig.getTioConfig(), userId, packet);
+ }
+ /**
+ * 发送到指定ip对应的集合
+ * @param ip
+ * @param packet
+ */
+ public static void sendToIp( String ip, ImPacket packet) {
+ sendToIp(ip, packet, null);
+ }
+
+ public static void sendToIp(String ip, ImPacket packet, ChannelContextFilter channelContextFilter) {
+ Tio.sendToIp(imConfig.getTioConfig(), ip, packet, channelContextFilter);
+ }
+
+ public static void sendToSet(SetWithLock setWithLock, ImPacket packet, ChannelContextFilter channelContextFilter, boolean isBlock){
+ Tio.sendToSet(imConfig.getTioConfig(),setWithLock,packet,channelContextFilter);
+ }
+ /**
+ * 绑定用户
+ * @param imChannelContext
+ * @param userId
+ */
+ public static void bindUser(ImChannelContext imChannelContext,String userId){
+ Tio.bindUser(imChannelContext.getTioChannelContext(), userId);
+ ImUserListener imUserListener = imConfig.getImUserListener();
+ if(imUserListener != null){
+ try {
+ imUserListener.onAfterBind(imChannelContext, userId);
+ }catch (ImException e){
+ log.error(e.toString(),e);
+ }
+ }
+ }
+ /**
+ * 解除userId的绑定。一般用于多地登录,踢掉前面登录的场景
+ * @param userId
+ * @author: WChao
+ */
+ public static void unbindUser(String userId){
+ TioConfig tioConfig = imConfig.getTioConfig();
+ Tio.unbindUser(tioConfig, userId);
+ ImUserListener imUserListener = imConfig.getImUserListener();
+ if(imUserListener == null){
+ return;
+ }
+ SetWithLock userChannels = Tio.getByUserid(tioConfig, userId);
+ Set channelContexts = userChannels.getObj();
+ if(!channelContexts.isEmpty()){
+ ReadLock readLock = userChannels.getLock().readLock();
+ try{
+ readLock.lock();
+ for (ChannelContext channelContext : channelContexts){
+ ImChannelContext imChannelContext = (ImChannelContext)channelContext.get(ImConst.Key.IM_CHANNEL_CONTEXT_KEY);
+ imUserListener.onAfterUnbind(imChannelContext, userId);
+ }
+ } catch (ImException e) {
+ log.error(e.toString(), e);
+ }finally {
+ readLock.unlock();
+ }
+ }
+ }
+ /**
+ * 绑定群组
+ * @param imChannelContext
+ * @param group
+ */
+ public static void bindGroup(ImChannelContext imChannelContext, String group){
+ Tio.bindGroup(imChannelContext.getTioChannelContext(), group);
+ }
+ /**
+ * 与指定组解除绑定关系
+ * @param groupId
+ * @param imChannelContext
+ * @author WChao
+ */
+ public static void unbindGroup(String groupId, ImChannelContext imChannelContext){
+ Tio.unbindGroup(groupId, imChannelContext.getTioChannelContext());
+ }
+ /**
+ * 与所有组解除解绑关系
+ * @param imChannelContext
+ * @author WChao
+ */
+ public static void unbindGroup(ImChannelContext imChannelContext){
+ Tio.unbindGroup(imChannelContext.getTioChannelContext());
+ }
+ /**
+ * 将制定用户从指定群组解除绑定
+ * @param userId
+ * @param group
+ */
+ public static void unbindGroup(String userId,String group){
+ Tio.unbindGroup(imConfig.getTioConfig(),userId,group);
+ }
+ /**
+ * 移除用户, 和close方法一样,只不过不再进行重连等维护性的操作
+ * @param userId
+ * @param remark
+ */
+ public static void remove(String userId,String remark){
+ SetWithLock userChannelContexts = Tio.getByUserid(imConfig.getTioConfig(), userId);
+ Set channels = userChannelContexts.getObj();
+ if(channels.isEmpty()){
+ return;
+ }
+ ReadLock readLock = userChannelContexts.getLock().readLock();
+ try{
+ readLock.lock();
+ for(ChannelContext channelContext : channels){
+ ImChannelContext imChannelContext = (ImChannelContext)channelContext.get(ImConst.Key.IM_CHANNEL_CONTEXT_KEY);
+ remove(imChannelContext, remark);
+ }
+ }finally{
+ readLock.unlock();
+ }
+ }
+ /**
+ * 移除指定channel, 和close方法一样,只不过不再进行重连等维护性的操作
+ * @param imChannelContext
+ * @param remark
+ */
+ public static void remove(ImChannelContext imChannelContext, String remark){
+ Tio.remove(imChannelContext.getTioChannelContext(), remark);
+ }
+ /**
+ * 关闭连接
+ * @param imChannelContext
+ * @param remark
+ */
+ public static void close(ImChannelContext imChannelContext, String remark){
+ Tio.close(imChannelContext.getTioChannelContext(), remark);
+ }
+
+}
diff --git a/jim-common/src/main/java/org/jim/common/Protocol.java b/jim-common/src/main/java/org/jim/common/Protocol.java
deleted file mode 100644
index 7590e11..0000000
--- a/jim-common/src/main/java/org/jim/common/Protocol.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.jim.common;
-
-public interface Protocol {
- /**
- * 心跳字节
- */
- public static final byte HEARTBEAT_BYTE = -128;
-
- /**
- * 握手字节
- */
- public static final byte HANDSHAKE_BYTE = -127;
-
- /**
- * 协议版本号
- */
- public final static byte VERSION = 0x01;
-
- public final static String WEBSOCKET = "ws";
-
- public final static String HTTP = "http";
-
- public final static String TCP = "tcp";
-
- public static final String COOKIE_NAME_FOR_SESSION = "jim-s";
- /**
- * 消息体最多为多少
- */
- public static final int MAX_LENGTH_OF_BODY = (int) (1024 * 1024 * 2.1); //只支持多少M数据
-
- /**
- * 消息头最少为多少个字节
- */
- public static final int LEAST_HEADER_LENGHT = 4;//1+1+2 + (2+4)
-
- /**
- * 加密标识位mask,1为加密,否则不加密
- */
- public static final byte FIRST_BYTE_MASK_ENCRYPT = -128;
-
- /**
- * 压缩标识位mask,1为压缩,否则不压缩
- */
- public static final byte FIRST_BYTE_MASK_COMPRESS = 0B01000000;
-
- /**
- * 是否有同步序列号标识位mask,如果有同步序列号,则消息头会带有同步序列号,否则不带
- */
- public static final byte FIRST_BYTE_MASK_HAS_SYNSEQ = 0B00100000;
-
- /**
- * 是否是用4字节来表示消息体的长度
- */
- public static final byte FIRST_BYTE_MASK_4_BYTE_LENGTH = 0B00010000;
-
- /**
- * 版本号mask
- */
- public static final byte FIRST_BYTE_MASK_VERSION = 0B00001111;
-}
\ No newline at end of file
diff --git a/jim-common/src/main/java/org/jim/common/SessionContext.java b/jim-common/src/main/java/org/jim/common/SessionContext.java
deleted file mode 100644
index 0eaa9d0..0000000
--- a/jim-common/src/main/java/org/jim/common/SessionContext.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- *
- */
-package org.jim.common;
-
-/**
- * 版本: [1.0]
- * 功能说明:
- * 作者: WChao 创建时间: 2017年8月3日 上午9:15:37
- */
-public class SessionContext {
- private String id;
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/Status.java b/jim-common/src/main/java/org/jim/common/Status.java
index 5d083d1..40277ba 100644
--- a/jim-common/src/main/java/org/jim/common/Status.java
+++ b/jim-common/src/main/java/org/jim/common/Status.java
@@ -10,7 +10,7 @@ package org.jim.common;
*/
public interface Status {
- public int getCode();
+ int getCode();
- public String getMsg();
+ String getMsg();
}
diff --git a/jim-common/src/main/java/org/jim/common/cache/redis/RedisConfigurationFactory.java b/jim-common/src/main/java/org/jim/common/cache/redis/RedisConfigurationFactory.java
index 15932e4..74632b8 100644
--- a/jim-common/src/main/java/org/jim/common/cache/redis/RedisConfigurationFactory.java
+++ b/jim-common/src/main/java/org/jim/common/cache/redis/RedisConfigurationFactory.java
@@ -8,7 +8,7 @@ import java.io.InputStream;
import java.net.URL;
import java.util.Properties;
-import org.jim.common.ImAio;
+import org.jim.common.Jim;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
@@ -87,7 +87,7 @@ public class RedisConfigurationFactory {
url = standardClassloader.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
}
if (url == null) {
- url = ImAio.class.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
+ url = Jim.class.getResource(DEFAULT_CLASSPATH_CONFIGURATION_FILE);
}
if (url != null) {
LOG.debug("Configuring redis from jim.properties found in the classpath: " + url);
diff --git a/jim-common/src/main/java/org/jim/common/cluster/ICluster.java b/jim-common/src/main/java/org/jim/common/cluster/ICluster.java
index 9ea3971..0ddc738 100644
--- a/jim-common/src/main/java/org/jim/common/cluster/ICluster.java
+++ b/jim-common/src/main/java/org/jim/common/cluster/ICluster.java
@@ -4,7 +4,6 @@
package org.jim.common.cluster;
import org.jim.common.ImPacket;
-import org.tio.core.GroupContext;
/**
*
@@ -12,8 +11,8 @@ import org.tio.core.GroupContext;
*
*/
public interface ICluster {
- public void clusterToUser(GroupContext groupContext, String userid,ImPacket packet);
- public void clusterToGroup(GroupContext groupContext, String group,ImPacket packet);
- public void clusterToIp(GroupContext groupContext, String ip,ImPacket packet);
- public void clusterToChannelId(GroupContext groupContext, String channelId,ImPacket packet);
+ public void clusterToUser(String userId,ImPacket packet);
+ public void clusterToGroup(String group,ImPacket packet);
+ public void clusterToIp(String ip,ImPacket packet);
+ public void clusterToChannelId(String channelId,ImPacket packet);
}
diff --git a/jim-common/src/main/java/org/jim/common/cluster/ImClusterConfig.java b/jim-common/src/main/java/org/jim/common/cluster/ImClusterConfig.java
index e23f883..9ef1d87 100644
--- a/jim-common/src/main/java/org/jim/common/cluster/ImClusterConfig.java
+++ b/jim-common/src/main/java/org/jim/common/cluster/ImClusterConfig.java
@@ -1,7 +1,5 @@
package org.jim.common.cluster;
-import org.tio.core.GroupContext;
-
/**
*
* @author WChao
@@ -30,7 +28,7 @@ public abstract class ImClusterConfig {
*/
private boolean cluster4all = true;
- protected GroupContext groupContext = null;
+ //protected GroupContext groupContext = null;
public abstract void send(ImClusterVo imClusterVo);
public abstract void sendAsyn(ImClusterVo imClusterVo);
diff --git a/jim-common/src/main/java/org/jim/common/cluster/redis/RedisCluster.java b/jim-common/src/main/java/org/jim/common/cluster/redis/RedisCluster.java
index 995493a..1cf8369 100644
--- a/jim-common/src/main/java/org/jim/common/cluster/redis/RedisCluster.java
+++ b/jim-common/src/main/java/org/jim/common/cluster/redis/RedisCluster.java
@@ -6,7 +6,6 @@ package org.jim.common.cluster.redis;
import org.jim.common.ImPacket;
import org.jim.common.cluster.ImCluster;
import org.jim.common.cluster.ImClusterVo;
-import org.tio.core.GroupContext;
/**
* @author WChao
*
@@ -18,7 +17,7 @@ public class RedisCluster extends ImCluster{
}
@Override
- public void clusterToUser(GroupContext groupContext, String userid,ImPacket packet) {
+ public void clusterToUser( String userid,ImPacket packet) {
if (clusterConfig.isCluster4user()) {
ImClusterVo imClusterVo = new ImClusterVo(packet);
imClusterVo.setUserid(userid);
@@ -27,7 +26,7 @@ public class RedisCluster extends ImCluster{
}
@Override
- public void clusterToGroup(GroupContext groupContext, String group,ImPacket packet) {
+ public void clusterToGroup(String group,ImPacket packet) {
if(clusterConfig.isCluster4group()){
ImClusterVo imClusterVo = new ImClusterVo(packet);
imClusterVo.setGroup(group);
@@ -36,7 +35,7 @@ public class RedisCluster extends ImCluster{
}
@Override
- public void clusterToIp(GroupContext groupContext, String ip,ImPacket packet) {
+ public void clusterToIp(String ip,ImPacket packet) {
if(clusterConfig.isCluster4ip()){
ImClusterVo imClusterVo = new ImClusterVo(packet);
imClusterVo.setIp(ip);
@@ -45,7 +44,7 @@ public class RedisCluster extends ImCluster{
}
@Override
- public void clusterToChannelId(GroupContext groupContext, String channelId,ImPacket packet) {
+ public void clusterToChannelId(String channelId,ImPacket packet) {
if(clusterConfig.isCluster4channelId()){
ImClusterVo imClusterVo = new ImClusterVo(packet);
imClusterVo.setChannelId(channelId);
diff --git a/jim-common/src/main/java/org/jim/common/cluster/redis/RedisClusterConfig.java b/jim-common/src/main/java/org/jim/common/cluster/redis/RedisClusterConfig.java
index 1cbd966..16e4bfb 100644
--- a/jim-common/src/main/java/org/jim/common/cluster/redis/RedisClusterConfig.java
+++ b/jim-common/src/main/java/org/jim/common/cluster/redis/RedisClusterConfig.java
@@ -7,7 +7,8 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImAio;
+import org.jim.common.ImConst;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.cluster.ImClusterConfig;
import org.jim.common.cluster.ImClusterVo;
@@ -16,8 +17,7 @@ import org.redisson.api.RedissonClient;
import org.redisson.api.listener.MessageListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
-import org.tio.core.GroupContext;
+import org.tio.core.Tio;
import org.tio.utils.json.Json;
/**
@@ -25,12 +25,10 @@ import org.tio.utils.json.Json;
* @author WChao
*
*/
-public class RedisClusterConfig extends ImClusterConfig {
+public class RedisClusterConfig extends ImClusterConfig implements ImConst {
private static Logger log = LoggerFactory.getLogger(RedisClusterConfig.class);
- public static final String IM_CLUSTER_TOPIC = "JIM_CLUSTER";
-
private String topicSuffix;
private String topic;
@@ -48,19 +46,15 @@ public class RedisClusterConfig extends ImClusterConfig {
* J-IM内置的集群是用redis的topic来实现的,所以不同groupContext就要有一个不同的topicSuffix
* @param topicSuffix 不同类型的groupContext就要有一个不同的topicSuffix
* @param redisson
- * @param groupContext
* @return
* @author: WChao
*/
- public static RedisClusterConfig newInstance(String topicSuffix, RedissonClient redisson, GroupContext groupContext) {
+ public static RedisClusterConfig newInstance(String topicSuffix, RedissonClient redisson) {
if (redisson == null) {
throw new RuntimeException(RedissonClient.class.getSimpleName() + "不允许为空");
}
- if (groupContext == null) {
- throw new RuntimeException("GroupContext不允许为空");
- }
- RedisClusterConfig me = new RedisClusterConfig(topicSuffix, redisson, groupContext);
+ RedisClusterConfig me = new RedisClusterConfig(topicSuffix, redisson);
me.rtopic = redisson.getTopic(me.topic);
me.rtopic.addListener(new MessageListener() {
@Override
@@ -86,53 +80,40 @@ public class RedisClusterConfig extends ImClusterConfig {
//发送给所有
boolean isToAll = imClusterVo.isToAll();
if (isToAll) {
- // for (GroupContext groupContext : me.groupContext) {
- Aio.sendToAll(groupContext, packet);
- // }
- //return;
+ Tio.sendToAll(null, packet);
}
//发送给指定组
String group = imClusterVo.getGroup();
if (StringUtils.isNotBlank(group)) {
- ImAio.sendToGroup(group, packet);
- //return;
+ Jim.sendToGroup(group, packet);
}
//发送给指定用户
String userid = imClusterVo.getUserid();
if (StringUtils.isNotBlank(userid)) {
- // for (GroupContext groupContext : me.groupContext) {
- ImAio.sendToUser(userid, packet);
- // }
- //return;
+ Jim.sendToUser(userid, packet);
}
//发送给指定token
String token = imClusterVo.getToken();
if (StringUtils.isNotBlank(token)) {
- // for (GroupContext groupContext : me.groupContext) {
- Aio.sendToToken(me.groupContext, token, packet);
- // }
- //return;
+ //Tio.sendToToken(me.groupContext, token, packet);
}
//发送给指定ip
String ip = imClusterVo.getIp();
if (StringUtils.isNotBlank(ip)) {
- // for (GroupContext groupContext : me.groupContext) {
- ImAio.sendToIp(me.groupContext, ip, packet);
- // }
- //return;
+ //Jim.sendToIp(me.groupContext, ip, packet);
}
}
});
return me;
}
- private RedisClusterConfig(String topicSuffix, RedissonClient redisson, GroupContext groupContext) {
+ private RedisClusterConfig(String topicSuffix, RedissonClient redisson) {
this.setTopicSuffix(topicSuffix);
this.setRedisson(redisson);
- this.groupContext = groupContext;
+ //this.groupContext = groupContext;
}
public String getTopicSuffix() {
return topicSuffix;
@@ -140,8 +121,7 @@ public class RedisClusterConfig extends ImClusterConfig {
public void setTopicSuffix(String topicSuffix) {
this.topicSuffix = topicSuffix;
- this.topic = topicSuffix + IM_CLUSTER_TOPIC;
-
+ this.topic = topicSuffix + Topic.JIM_CLUSTER_TOPIC;
}
public String getTopic() {
diff --git a/jim-common/src/main/java/org/jim/common/config/Config.java b/jim-common/src/main/java/org/jim/common/config/Config.java
deleted file mode 100644
index 829c6f0..0000000
--- a/jim-common/src/main/java/org/jim/common/config/Config.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- *
- */
-package org.jim.common.config;
-
-import org.jim.common.cluster.ImCluster;
-import org.jim.common.message.MessageHelper;
-import org.tio.core.GroupContext;
-import org.tio.core.intf.GroupListener;
-import org.tio.core.ssl.SslConfig;
-
-/**
- * @author WChao
- * 2018/08/26
- */
-public class Config {
- /**
- * IP地址
- */
- protected String bindIp = null;
- /**
- * 监听端口
- */
- protected Integer bindPort = 80;
- /**
- * 心跳包发送时长heartbeatTimeout/2
- */
- protected long heartbeatTimeout = 0;
-
- /**
- * 全局群组上下文;
- */
- protected GroupContext groupContext;
- /**
- * 群组监听器;
- */
- protected GroupListener imGroupListener;
- /**
- * 用户消息持久化助手;
- */
- protected MessageHelper messageHelper;
- /**
- * 是否开启持久化;
- */
- protected String isStore = "off";
- /**
- * 是否开启集群;
- */
- protected String isCluster = "off";
- /**
- * 是否开启SSL加密
- */
- protected String isSSL = "off";
- /**
- * SSL配置
- */
- protected SslConfig sslConfig;
- /**
- * 集群配置
- * 如果此值不为null,就表示要集群
- */
- protected ImCluster cluster;
- /**
- * 默认的接收数据的buffer size
- */
- protected long readBufferSize = 1024 * 2;
-
- public String getBindIp() {
- return bindIp;
- }
-
- public void setBindIp(String bindIp) {
- this.bindIp = bindIp;
- }
-
- public Integer getBindPort() {
- return bindPort;
- }
-
- public void setBindPort(Integer bindPort) {
- this.bindPort = bindPort;
- }
-
- public long getHeartbeatTimeout() {
- return heartbeatTimeout;
- }
-
- public void setHeartbeatTimeout(long heartbeatTimeout) {
- this.heartbeatTimeout = heartbeatTimeout;
- }
-
- public GroupContext getGroupContext() {
- return groupContext;
- }
-
- public void setGroupContext(GroupContext groupContext) {
- this.groupContext = groupContext;
- }
-
- public GroupListener getImGroupListener() {
- return imGroupListener;
- }
-
- public void setImGroupListener(GroupListener imGroupListener) {
- this.imGroupListener = imGroupListener;
- }
-
- public MessageHelper getMessageHelper() {
- return messageHelper;
- }
-
- public void setMessageHelper(MessageHelper messageHelper) {
- this.messageHelper = messageHelper;
- }
-
- public String getIsStore() {
- return isStore;
- }
-
- public void setIsStore(String isStore) {
- this.isStore = isStore;
- }
-
- public String getIsCluster() {
- return isCluster;
- }
-
- public void setIsCluster(String isCluster) {
- this.isCluster = isCluster;
- }
-
- public String getIsSSL() {
- return isSSL;
- }
-
- public void setIsSSL(String isSSL) {
- this.isSSL = isSSL;
- }
-
- public SslConfig getSslConfig() {
- return sslConfig;
- }
-
- public void setSslConfig(SslConfig sslConfig) {
- this.sslConfig = sslConfig;
- }
-
- public ImCluster getCluster() {
- return cluster;
- }
-
- public void setCluster(ImCluster cluster) {
- this.cluster = cluster;
- }
-
- public long getReadBufferSize() {
- return readBufferSize;
- }
-
- public void setReadBufferSize(long readBufferSize) {
- this.readBufferSize = readBufferSize;
- }
-
- public interface Builder {
- /**
- * 配置构建接口
- * @return
- * @throws Exception
- */
- Config build() throws Exception;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/config/DefaultImConfigBuilder.java b/jim-common/src/main/java/org/jim/common/config/DefaultImConfigBuilder.java
deleted file mode 100644
index e56a0c2..0000000
--- a/jim-common/src/main/java/org/jim/common/config/DefaultImConfigBuilder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- *
- */
-package org.jim.common.config;
-
-import org.jim.common.http.HttpConfig;
-import org.jim.common.ws.WsServerConfig;
-
-/**
- * @author WChao
- *
- */
-public class DefaultImConfigBuilder extends ImConfigBuilder {
-
- /* (non-Javadoc)
- * @see org.jim.common.config.ImConfigBuilder#configHttp(org.jim.common.http.HttpConfig)
- */
- @Override
- public ImConfigBuilder configHttp(HttpConfig httpConfig) {
- // TODO Auto-generated method stub
- return this;
- }
-
- /* (non-Javadoc)
- * @see org.jim.common.config.ImConfigBuilder#configWs(org.jim.common.ws.WsServerConfig)
- */
- @Override
- public ImConfigBuilder configWs(WsServerConfig wsServerConfig) {
- // TODO Auto-generated method stub
- return this;
- }
-
-}
diff --git a/jim-common/src/main/java/org/jim/common/config/ImConfig.java b/jim-common/src/main/java/org/jim/common/config/ImConfig.java
new file mode 100644
index 0000000..7d614e9
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/config/ImConfig.java
@@ -0,0 +1,278 @@
+/**
+ *
+ */
+package org.jim.common.config;
+
+import org.jim.common.ImConst;
+import org.jim.common.ImHandler;
+import org.jim.common.listener.ImGroupListener;
+import org.jim.common.listener.ImGroupListenerAdapter;
+import org.jim.common.listener.ImListener;
+import org.jim.common.listener.ImUserListener;
+import org.tio.core.TioConfig;
+import org.tio.utils.Threads;
+import org.tio.utils.prop.MapWithLockPropSupport;
+import org.tio.utils.thread.pool.DefaultThreadFactory;
+import org.tio.utils.thread.pool.SynThreadPoolExecutor;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * @author WChao
+ *
+ */
+public abstract class ImConfig extends MapWithLockPropSupport implements ImConst{
+ /**
+ * IP地址
+ */
+ protected String bindIp;
+ /**
+ * 监听端口
+ */
+ protected Integer bindPort = 80;
+
+ /**
+ * 默认的接收数据的buffer size
+ */
+ protected int readBufferSize = 1024 * 2;
+ /**
+ * 配置名称
+ */
+ protected String name = "j-im";
+
+ /**
+ * tio相关配置信息
+ */
+ protected TioConfig tioConfig;
+
+ /**
+ * 心跳包发送时长heartbeatTimeout/2
+ */
+ protected long heartbeatTimeout = 0;
+
+ protected SynThreadPoolExecutor jimExecutor;
+ /**
+ * 群组绑定监听器
+ */
+ protected ImGroupListener imGroupListener;
+ /**
+ * 用户绑定监听器
+ */
+ protected ImUserListener imUserListener;
+
+ private static int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
+
+ public ImConfig(){
+ this(null);
+ }
+
+ public ImConfig(SynThreadPoolExecutor jimExecutor){
+ this.jimExecutor = jimExecutor;
+ if (this.jimExecutor == null) {
+ LinkedBlockingQueue timQueue = new LinkedBlockingQueue<>();
+ this.jimExecutor = new SynThreadPoolExecutor(CORE_POOL_SIZE, CORE_POOL_SIZE, Threads.KEEP_ALIVE_TIME, timQueue,
+ DefaultThreadFactory.getInstance(ImConst.JIM, Thread.NORM_PRIORITY), ImConst.JIM);
+ this.jimExecutor.prestartAllCoreThreads();
+ }
+ }
+
+ public static class Const{
+
+ public static final String ON = "on";
+
+ public static final String OFF = "off";
+
+ }
+ /**
+ * 获取ImHandler对象
+ * @return
+ * @author: WChao
+ */
+ public abstract ImHandler getImHandler();
+
+ /**
+ * 获取ImListener对象
+ * @return
+ * @author: WChao
+ */
+ public abstract ImListener getImListener();
+
+ public static class Global{
+
+ private static ImConfig global;
+
+ public static C get(){
+ return (C) global;
+ }
+
+ public static C set(C c){
+ global = (ImConfig) c;
+ return (C) global;
+ }
+ }
+
+ public abstract static class Builder> {
+
+ /**
+ * IP地址
+ */
+ protected String bindIp;
+ /**
+ * 监听端口
+ */
+ protected Integer bindPort = 80;
+ /**
+ * 配置名称
+ */
+ protected String name = "j-im";
+
+ /**
+ * 默认的接收数据的buffer size
+ */
+ protected int readBufferSize = 1024 * 2;
+
+ /**
+ * 心跳包发送时长heartbeatTimeout/2
+ */
+ protected long heartbeatTimeout = 0;
+
+ /**
+ * tio相关配置信息
+ */
+ protected TioConfig tioConfig;
+
+ /**
+ * 群组绑定监听器
+ */
+ protected ImGroupListener imGroupListener;
+ /**
+ * 用户绑定监听器
+ */
+ protected ImUserListener imUserListener;
+
+
+ private B theBuilder = this.getThis();
+
+ /**
+ * 供子类获取自身builder抽象类;
+ * @return
+ */
+ protected abstract B getThis();
+
+ public B bindIp(String bindIp){
+ this.bindIp = bindIp;
+ return theBuilder;
+ }
+
+ public B bindPort(Integer bindPort){
+ this.bindPort = bindPort;
+ return theBuilder;
+ }
+
+ public B name(String name){
+ this.name = name;
+ return theBuilder;
+ }
+
+ public B heartbeatTimeout(long heartbeatTimeout){
+ this.heartbeatTimeout = heartbeatTimeout;
+ return theBuilder;
+ }
+
+ public B readBufferSize(int readBufferSize){
+ this.readBufferSize = readBufferSize;
+ return theBuilder;
+ }
+
+ public B tioConfig(TioConfig tioConfig){
+ this.tioConfig = tioConfig;
+ return theBuilder;
+ }
+ public B groupListener(ImGroupListener imGroupListener){
+ this.imGroupListener = imGroupListener;
+ return theBuilder;
+ }
+ public B userListener(ImUserListener imUserListener){
+ this.imUserListener = imUserListener;
+ return theBuilder;
+ }
+ /**
+ * 配置构建接口
+ * @return
+ * @throws Exception
+ */
+ public abstract T build();
+ }
+
+ public String getBindIp() {
+ return bindIp;
+ }
+
+ public void setBindIp(String bindIp) {
+ this.bindIp = bindIp;
+ }
+
+ public Integer getBindPort() {
+ return bindPort;
+ }
+
+ public void setBindPort(Integer bindPort) {
+ this.bindPort = bindPort;
+ }
+
+ public int getReadBufferSize() {
+ return readBufferSize;
+ }
+
+ public void setReadBufferSize(int readBufferSize) {
+ this.readBufferSize = readBufferSize;
+ tioConfig.setReadBufferSize(readBufferSize);
+ }
+
+ public TioConfig getTioConfig() {
+ return tioConfig;
+ }
+
+ public void setTioConfig(TioConfig tioConfig) {
+ this.tioConfig = tioConfig;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getHeartbeatTimeout() {
+ return heartbeatTimeout;
+ }
+ public void setHeartbeatTimeout(long heartbeatTimeout) {
+ this.heartbeatTimeout = heartbeatTimeout;
+ tioConfig.setHeartbeatTimeout(heartbeatTimeout);
+ }
+
+ public SynThreadPoolExecutor getJimExecutor() {
+ return jimExecutor;
+ }
+
+ public ImGroupListener getImGroupListener() {
+ return imGroupListener;
+ }
+
+ public void setImGroupListener(ImGroupListener imGroupListener) {
+ this.imGroupListener = imGroupListener;
+ if(imGroupListener != null) {
+ this.tioConfig.setGroupListener(new ImGroupListenerAdapter(this.imGroupListener));
+ }
+ }
+
+ public ImUserListener getImUserListener() {
+ return imUserListener;
+ }
+
+ public void setImUserListener(ImUserListener imUserListener) {
+ this.imUserListener = imUserListener;
+ }
+}
diff --git a/jim-common/src/main/java/org/jim/common/config/ImConfigBuilder.java b/jim-common/src/main/java/org/jim/common/config/ImConfigBuilder.java
deleted file mode 100644
index d8bc69c..0000000
--- a/jim-common/src/main/java/org/jim/common/config/ImConfigBuilder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- *
- */
-package org.jim.common.config;
-
-import org.jim.common.ImConfig;
-import org.jim.common.cluster.ImCluster;
-import org.jim.common.http.HttpConfig;
-import org.jim.common.message.MessageHelper;
-import org.jim.common.ws.WsServerConfig;
-import org.tio.core.GroupContext;
-import org.tio.core.intf.GroupListener;
-import org.tio.core.ssl.SslConfig;
-
-/**
- * @author WChao
- * 2018/08/26
- */
-public abstract class ImConfigBuilder implements Config.Builder {
-
- protected ImConfig conf;
-
- public ImConfigBuilder() {
- this.conf = new ImConfig();
- }
-
- public abstract ImConfigBuilder configHttp(HttpConfig httpConfig);
- public abstract ImConfigBuilder configWs(WsServerConfig wsServerConfig);
-
- public ImConfigBuilder setBindIp(String bindIp) {
- this.conf.bindIp = bindIp;
- return this;
- }
-
- public ImConfigBuilder setBindPort(Integer bindPort) {
- this.conf.bindPort = bindPort;
- return this;
- }
-
- public ImConfigBuilder setHeartbeatTimeout(long heartbeatTimeout) {
- this.conf.heartbeatTimeout = heartbeatTimeout;
- return this;
- }
-
- public ImConfigBuilder setGroupContext(GroupContext groupContext) {
- this.conf.groupContext = groupContext;
- return this;
- }
-
- public ImConfigBuilder setImGroupListener(GroupListener imGroupListener) {
- this.conf.imGroupListener = imGroupListener;
- return this;
- }
-
- public ImConfigBuilder setMessageHelper(MessageHelper messageHelper) {
- this.conf.messageHelper = messageHelper;
- return this;
- }
-
- public ImConfigBuilder setIsStore(String isStore) {
- this.conf.isStore = isStore;
- return this;
- }
-
- public ImConfigBuilder setIsCluster(String isCluster) {
- this.conf.isCluster = isCluster;
- return this;
- }
-
- public ImConfigBuilder setIsSSL(String isSSL) {
- this.conf.isSSL = isSSL;
- return this;
- }
-
- public ImConfigBuilder setSslConfig(SslConfig sslConfig) {
- this.conf.sslConfig = sslConfig;
- return this;
- }
-
- public ImConfigBuilder setCluster(ImCluster cluster) {
- this.conf.cluster = cluster;
- return this;
- }
-
- public ImConfigBuilder setReadBufferSize(long readBufferSize) {
- this.conf.readBufferSize = readBufferSize;
- return this;
- }
-
- @Override
- public ImConfig build() {
- this.configHttp(conf.getHttpConfig());
- this.configWs(conf.getWsServerConfig());
- return conf;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/config/PropertyImConfigBuilder.java b/jim-common/src/main/java/org/jim/common/config/PropertyImConfigBuilder.java
deleted file mode 100644
index 95ec322..0000000
--- a/jim-common/src/main/java/org/jim/common/config/PropertyImConfigBuilder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *
- */
-package org.jim.common.config;
-
-import org.jim.common.ImConfig;
-import org.jim.common.http.HttpConfig;
-import org.jim.common.utils.PropUtil;
-import org.jim.common.ws.WsServerConfig;
-/**
- * @author WChao
- * 2018/08/26
- */
-public class PropertyImConfigBuilder extends ImConfigBuilder {
-
- public PropertyImConfigBuilder(String file) {
- PropUtil.use(file);
- }
-
- @Override
- public ImConfigBuilder configHttp(HttpConfig httpConfig) {
- //html/css/js等的根目录,支持classpath:,也支持绝对路径
- String pageRoot = PropUtil.get("jim.http.page");
- //j-im mvc需要扫描的根目录包
- String[] scanPackages = PropUtil.get("jim.http.scan.packages").split(",");
- httpConfig.setBindPort((PropUtil.getInt("jim.port")));
- //设置web访问路径;
- httpConfig.setPageRoot(pageRoot);
- //不缓存资源;
- httpConfig.setMaxLiveTimeOfStaticRes(PropUtil.getInt("jim.http.max.live.time"));
- //设置j-im mvc扫描目录;
- httpConfig.setScanPackages(scanPackages);
- return this;
- }
-
- @Override
- public ImConfigBuilder configWs(WsServerConfig wsServerConfig) {
-
- return this;
- }
-
- @Override
- public ImConfig build() {
- super.build();
- this.setBindIp(PropUtil.get("jim.bind.ip"));
- this.setBindPort(PropUtil.getInt("jim.port"));
- this.setHeartbeatTimeout(PropUtil.getLong("jim.heartbeat.timeout"));
- this.setIsStore(PropUtil.get("jim.store"));
- this.setIsCluster(PropUtil.get("jim.cluster"));
- return conf;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/exception/ImDecodeException.java b/jim-common/src/main/java/org/jim/common/exception/ImDecodeException.java
new file mode 100644
index 0000000..e003647
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/exception/ImDecodeException.java
@@ -0,0 +1,22 @@
+package org.jim.common.exception;
+
+import org.tio.core.exception.LengthOverflowException;
+
+/**
+ * @ClassName ImDecodeException
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/11 6:02
+ * @Version 1.0
+ **/
+public class ImDecodeException extends ImException {
+
+ public ImDecodeException(Throwable e) {
+ super(e);
+ }
+
+ public ImDecodeException(String message) {
+ super(message);
+
+ }
+}
diff --git a/jim-common/src/main/java/org/jim/common/exception/ImException.java b/jim-common/src/main/java/org/jim/common/exception/ImException.java
index 9b21ce0..9163b4f 100644
--- a/jim-common/src/main/java/org/jim/common/exception/ImException.java
+++ b/jim-common/src/main/java/org/jim/common/exception/ImException.java
@@ -12,7 +12,7 @@ public class ImException extends Exception{
/**
* @Author WChao
* @Description //TODO
- * @param []
+ * @param
* @return
**/
public ImException() {
@@ -21,7 +21,7 @@ public class ImException extends Exception{
/**
* @Author WChao
* @Description //TODO
- * @param [message]
+ * @param message
* @return
**/
public ImException(String message) {
@@ -32,7 +32,7 @@ public class ImException extends Exception{
/**
* @Author WChao
* @Description //TODO
- * @param [message, cause]
+ * @param message, cause
* @return
**/
public ImException(String message, Throwable cause) {
@@ -43,7 +43,7 @@ public class ImException extends Exception{
/**
* @Author WChao
* @Description //TODO
- * @param [message, cause, enableSuppression, writableStackTrace]
+ * @param message, cause, enableSuppression, writableStackTrace
* @return
**/
public ImException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
@@ -54,7 +54,7 @@ public class ImException extends Exception{
/**
* @Author WChao
* @Description //TODO
- * @param [cause]
+ * @param cause
* @return
**/
public ImException(Throwable cause) {
diff --git a/jim-common/src/main/java/org/jim/common/http/Cookie.java b/jim-common/src/main/java/org/jim/common/http/Cookie.java
index d31ee14..8baccc6 100644
--- a/jim-common/src/main/java/org/jim/common/http/Cookie.java
+++ b/jim-common/src/main/java/org/jim/common/http/Cookie.java
@@ -9,6 +9,7 @@ import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.jim.common.ImConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,7 +18,7 @@ import org.slf4j.LoggerFactory;
* @author wchao
* 2017年5月29日 上午7:45:58
*/
-public class Cookie {
+public class Cookie implements ImConst {
private static Logger log = LoggerFactory.getLogger(Cookie.class);
/**
@@ -50,7 +51,7 @@ public class Cookie {
default:
cookie.setName(cookieMapItem.getKey());
try {
- cookie.setValue(URLDecoder.decode(cookieMapItem.getValue(), HttpConst.CHARSET_NAME));
+ cookie.setValue(URLDecoder.decode(cookieMapItem.getValue(), Http.CHARSET_NAME));
} catch (UnsupportedEncodingException e) {
log.error(e.toString(), e);
}
diff --git a/jim-common/src/main/java/org/jim/common/http/GroupContextKey.java b/jim-common/src/main/java/org/jim/common/http/GroupContextKey.java
deleted file mode 100644
index 945486f..0000000
--- a/jim-common/src/main/java/org/jim/common/http/GroupContextKey.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.jim.common.http;
-
-/**
- * @author wchao
- * 2017年8月18日 下午5:43:54
- */
-public interface GroupContextKey {
- /**
- * 存放HttpConfig
- */
- String HTTP_SERVER_CONFIG = "TIO_HTTP_SERVER_CONFIG";
-}
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpConfig.java b/jim-common/src/main/java/org/jim/common/http/HttpConfig.java
index ef97ccb..7f7207f 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpConfig.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpConfig.java
@@ -1,6 +1,6 @@
package org.jim.common.http;
-import org.jim.common.config.Config;
+import org.jim.common.ImConst;
import org.jim.common.http.handler.IHttpRequestHandler;
import org.jim.common.http.listener.IHttpServerListener;
import org.jim.common.session.id.ISessionIdGenerator;
@@ -10,19 +10,24 @@ import org.tio.utils.cache.ICache;
* @author wchao
* 2017年8月15日 下午1:21:14
*/
-public class HttpConfig extends Config{
-
- // private static Logger log = LoggerFactory.getLogger(HttpConfig.class);
-
+public class HttpConfig implements ImConst {
+ /**
+ * IP地址
+ */
+ protected String bindIp;
+ /**
+ * 监听端口
+ */
+ protected Integer bindPort = 80;
/**
* 存放HttpSession对象的cacheName
*/
- public static final String SESSION_CACHE_NAME = "tio-h-s";
+ public static final String SESSION_CACHE_NAME = "jim-h-s";
/**
* 存放sessionId的cookie name
*/
- public static final String SESSION_COOKIE_NAME = "TwIxO";
+ public static final String SESSION_COOKIE_NAME = "jimIxO";
/**
* session默认的超时时间,单位:秒
@@ -32,7 +37,7 @@ public class HttpConfig extends Config{
/**
* 默认的静态资源缓存时间,单位:秒
*/
- public static final int MAX_LIVETIME_OF_STATICRES = 60 * 10;
+ public static final int MAX_LIVE_TIME_OF_STATICS = 60 * 10;
/**
* 文件上传时,boundary值的最大长度
@@ -49,17 +54,9 @@ public class HttpConfig extends Config{
*/
public static final int MAX_LENGTH_OF_MULTI_BODY = 1024 * 1024 * 20;
- /**
- * @param args
- * @author wchao
- */
- public static void main(String[] args) {
+ private String serverInfo = Http.SERVER_INFO;
- }
-
- private String serverInfo = HttpConst.SERVER_INFO;
-
- private String charset = HttpConst.CHARSET_NAME;
+ private String charset = Http.CHARSET_NAME;
private ICache sessionStore = null;
@@ -72,14 +69,14 @@ public class HttpConfig extends Config{
/**
* session超时时间,单位:秒
*/
- private long sessionTimeout = DEFAULT_SESSION_TIMEOUT;
+ private Long sessionTimeout = DEFAULT_SESSION_TIMEOUT;
private String sessionCookieName = SESSION_COOKIE_NAME;
/**
* 静态资源缓存时间,如果小于等于0则不缓存,单位:秒
*/
- private int maxLiveTimeOfStaticRes = MAX_LIVETIME_OF_STATICRES;
+ private Integer maxLiveTimeOfStaticRes = MAX_LIVE_TIME_OF_STATICS;
private String page404 = "/404.html";
@@ -97,36 +94,138 @@ public class HttpConfig extends Config{
* 2、绝对路径:/page
* //FileUtil.getAbsolutePath("page");//"/page";
*/
- private String pageRoot = null;
+ private String pageRoot = "page";
/**
* mvc扫描包路径;
*/
private String[] scanPackages = null;
-
- public HttpConfig() {}
-
- /**
- *
- * @author wchao
- */
- public HttpConfig(Integer bindPort, Long sessionTimeout) {
- this.bindPort = bindPort;
- if (sessionTimeout != null) {
+ public HttpConfig(IHttpRequestHandler httpRequestHandler, IHttpServerListener httpServerListener){
+ setHttpRequestHandler(httpRequestHandler);
+ setHttpServerListener(httpServerListener);
+ }
+
+ public static HttpConfig.Builder newBuilder(){
+ return new HttpConfig.Builder();
+ }
+
+ public static class Builder{
+
+ private String charset = Http.CHARSET_NAME;
+
+ private ICache sessionStore;
+
+ private Long sessionTimeout = DEFAULT_SESSION_TIMEOUT;
+
+ /**
+ * 静态资源缓存时间,如果小于等于0则不缓存,单位:秒
+ */
+ private Integer maxLiveTimeOfStaticRes = MAX_LIVE_TIME_OF_STATICS;
+
+ private String page404 = "/404.html";
+
+ private String page500 = "/500.html";
+
+ private ISessionIdGenerator sessionIdGenerator;
+
+ private IHttpRequestHandler httpRequestHandler;
+
+ private IHttpServerListener httpServerListener;
+
+ private String pageRoot = "page";
+
+ private String[] scanPackages = null;
+
+ public Builder charset(String charset){
+ this.charset = charset;
+ return this;
+ }
+
+ public Builder sessionStore(ICache sessionStore){
+ this.sessionStore = sessionStore;
+ return this;
+ }
+
+ public Builder sessionTimeout(Long sessionTimeout){
this.sessionTimeout = sessionTimeout;
+ return this;
+ }
+
+ public Builder maxLiveTimeOfStaticRes(int maxLiveTimeOfStaticRes){
+ this.maxLiveTimeOfStaticRes = maxLiveTimeOfStaticRes;
+ return this;
+ }
+
+ public Builder page404(String page404){
+ this.page404 = page404;
+ return this;
+ }
+
+ public Builder page500(String page500){
+ this.page500 = page500;
+ return this;
+ }
+
+ public Builder sessionIdGenerator(ISessionIdGenerator sessionIdGenerator){
+ this.sessionIdGenerator = sessionIdGenerator;
+ return this;
+ }
+
+ public Builder httpRequestHandler(IHttpRequestHandler httpRequestHandler){
+ this.httpRequestHandler = httpRequestHandler;
+ return this;
+ }
+
+ public Builder httpServerListener(IHttpServerListener httpServerListener){
+ this.httpServerListener = httpServerListener;
+ return this;
+ }
+
+ public Builder pageRoot(String pageRoot){
+ this.pageRoot = pageRoot;
+ return this;
+ }
+
+ public Builder scanPackages(String[] scanPackages){
+ this.scanPackages = scanPackages;
+ return this;
+ }
+
+ public HttpConfig build(){
+ HttpConfig httpConfig = new HttpConfig(this.httpRequestHandler, this.httpServerListener);
+ httpConfig.setCharset(this.charset);
+ httpConfig.setSessionStore(this.sessionStore);
+ httpConfig.setSessionTimeout(this.sessionTimeout);
+ httpConfig.setMaxLiveTimeOfStaticRes(maxLiveTimeOfStaticRes);
+ httpConfig.setPage404(page404);
+ httpConfig.setPage500(page500);
+ httpConfig.setSessionIdGenerator(sessionIdGenerator);
+ httpConfig.setPageRoot(pageRoot);
+ httpConfig.setScanPackages(scanPackages);
+ return httpConfig;
}
}
-
- /**
- * @return the charset
- */
+
public String getCharset() {
return charset;
}
- /**
- * @return the maxLiveTimeOfStaticRes
- */
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
+
+ public ICache getSessionStore() {
+ return sessionStore;
+ }
+
+ public void setSessionStore(ICache sessionStore) {
+ this.sessionStore = sessionStore;
+ }
+
+ public Long getSessionTimeout() {
+ return sessionTimeout;
+ }
+
public int getMaxLiveTimeOfStaticRes() {
return maxLiveTimeOfStaticRes;
}
@@ -135,127 +234,34 @@ public class HttpConfig extends Config{
return page404;
}
- public String getPage500() {
- return page500;
- }
-
- /**
- * @return the pageRoot
- */
- public String getPageRoot() {
- return pageRoot;
- }
-
- /**
- * @return the serverInfo
- */
- public String getServerInfo() {
- return serverInfo;
- }
-
- /**
- * @return the sessionCacheName
- */
- public String getSessionCacheName() {
- return sessionCacheName;
- }
-
- public String getSessionCookieName() {
- return sessionCookieName;
- }
-
- public ISessionIdGenerator getSessionIdGenerator() {
- return sessionIdGenerator;
- }
-
- public ICache getSessionStore() {
- return sessionStore;
- }
-
- public long getSessionTimeout() {
- return sessionTimeout;
- }
-
- /**
- * @param charset the charset to set
- */
- public void setCharset(String charset) {
- this.charset = charset;
- }
-
- /**
- * @param maxLiveTimeOfStaticRes the maxLiveTimeOfStaticRes to set
- */
- public void setMaxLiveTimeOfStaticRes(int maxLiveTimeOfStaticRes) {
- this.maxLiveTimeOfStaticRes = maxLiveTimeOfStaticRes;
- }
-
public void setPage404(String page404) {
this.page404 = page404;
}
+ public String getPage500() {
+ return page500;
+ }
+
public void setPage500(String page500) {
this.page500 = page500;
}
- /**
- *
- * @param pageRoot
- * @author wchao
- */
- public void setPageRoot(String pageRoot) {
- this.pageRoot = pageRoot;//FileUtil.getAbsolutePath(root);//"/page";;
- }
-
- /**
- * @param serverInfo the serverInfo to set
- */
- public void setServerInfo(String serverInfo) {
- this.serverInfo = serverInfo;
- }
-
- /**
- * @param sessionCacheName the sessionCacheName to set
- */
- public void setSessionCacheName(String sessionCacheName) {
- this.sessionCacheName = sessionCacheName;
- }
-
- public void setSessionCookieName(String sessionCookieName) {
- this.sessionCookieName = sessionCookieName;
+ public ISessionIdGenerator getSessionIdGenerator() {
+ return sessionIdGenerator;
}
public void setSessionIdGenerator(ISessionIdGenerator sessionIdGenerator) {
this.sessionIdGenerator = sessionIdGenerator;
}
- public void setSessionStore(ICache sessionStore) {
- this.sessionStore = sessionStore;
- // this.httpSessionManager = HttpSessionManager.getInstance(sessionStore);
- }
-
- /**
- * @return the httpRequestHandler
- */
public IHttpRequestHandler getHttpRequestHandler() {
return httpRequestHandler;
}
- /**
- * @param httpRequestHandler the httpRequestHandler to set
- */
public void setHttpRequestHandler(IHttpRequestHandler httpRequestHandler) {
this.httpRequestHandler = httpRequestHandler;
}
- public String[] getScanPackages() {
- return scanPackages;
- }
-
- public void setScanPackages(String[] scanPackages) {
- this.scanPackages = scanPackages;
- }
-
public IHttpServerListener getHttpServerListener() {
return httpServerListener;
}
@@ -264,4 +270,55 @@ public class HttpConfig extends Config{
this.httpServerListener = httpServerListener;
}
+ public String getPageRoot() {
+ return pageRoot;
+ }
+
+ public void setPageRoot(String pageRoot) {
+ this.pageRoot = pageRoot;
+ }
+
+ public String[] getScanPackages() {
+ return scanPackages;
+ }
+
+ public void setScanPackages(String[] scanPackages) {
+ this.scanPackages = scanPackages;
+ }
+
+ public String getServerInfo() {
+ return serverInfo;
+ }
+
+ public String getSessionCacheName() {
+ return sessionCacheName;
+ }
+
+ public String getSessionCookieName() {
+ return sessionCookieName;
+ }
+
+ public String getBindIp() {
+ return bindIp;
+ }
+
+ public void setBindIp(String bindIp) {
+ this.bindIp = bindIp;
+ }
+
+ public Integer getBindPort() {
+ return bindPort;
+ }
+
+ public void setBindPort(Integer bindPort) {
+ this.bindPort = bindPort;
+ }
+
+ public void setSessionTimeout(Long sessionTimeout) {
+ this.sessionTimeout = sessionTimeout;
+ }
+
+ public void setMaxLiveTimeOfStaticRes(Integer maxLiveTimeOfStaticRes) {
+ this.maxLiveTimeOfStaticRes = maxLiveTimeOfStaticRes;
+ }
}
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpConst.java b/jim-common/src/main/java/org/jim/common/http/HttpConst.java
index 403a499..d61a8fd 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpConst.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpConst.java
@@ -7,182 +7,5 @@ package org.jim.common.http;
*/
public interface HttpConst {
- /**
- * 请求体的格式
- * @author wchao
- * 2017年6月28日 上午10:03:12
- */
- public enum RequestBodyFormat {
- URLENCODED, MULTIPART, TEXT
- }
- /**
- * Accept-Language : zh-CN,zh;q=0.8
- Sec-WebSocket-Version : 13
- Sec-WebSocket-Extensions : permessage-deflate; client_max_window_bits
- Upgrade : websocket
- Host : t-io.org:9321
- Accept-Encoding : gzip, deflate, sdch
- User-Agent : Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
- Origin : http://www.t-io.org:9292
- Sec-WebSocket-Key : kmCL2C7q9vtNSMyHpft7lw==
- Connection : Upgrade
- Cache-Control : no-cache
- Pragma : no-cache
- *
- * @author wchao
- * 2017年5月27日 下午2:11:57
- */
- public interface RequestHeaderKey {
- String Cookie = "Cookie".toLowerCase();//Cookie: $Version=1; Skin=new;
- String Origin = "Origin".toLowerCase(); //http://127.0.0.1
- String Sec_WebSocket_Key = "Sec-WebSocket-Key".toLowerCase(); //2GFwqJ1Z37glm62YKKLUeA==
- String Cache_Control = "Cache-Control".toLowerCase(); //no-cache
- String Connection = "Connection".toLowerCase(); //Upgrade, keep-alive
- String User_Agent = "User-Agent".toLowerCase(); //Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3088.3 Safari/537.36
- String Sec_WebSocket_Version = "Sec-WebSocket-Version".toLowerCase(); //13
- String Host = "Host".toLowerCase(); //127.0.0.1:9321
- String Pragma = "Pragma".toLowerCase(); //no-cache
- String Accept_Encoding = "Accept-Encoding".toLowerCase(); //gzip, deflate, br
- String Accept_Language = "Accept-Language".toLowerCase(); //zh-CN,zh;q=0.8,en;q=0.6
- String Upgrade = "Upgrade".toLowerCase(); //websocket
- String Sec_WebSocket_Extensions = "Sec-WebSocket-Extensions".toLowerCase(); //permessage-deflate; client_max_window_bits
- String Content_Length = "Content-Length".toLowerCase(); //65
- String Content_Type = "Content-Type".toLowerCase();// : 【application/x-www-form-urlencoded】【application/x-www-form-urlencoded; charset=UTF-8】【multipart/form-data; boundary=----WebKitFormBoundaryuwYcfA2AIgxqIxA0 】
- String If_Modified_Since = "If-Modified-Since".toLowerCase(); //与Last-Modified配合
-
- /**
- * 值为XMLHttpRequest则为Ajax
- */
- String X_Requested_With = "X-Requested-With".toLowerCase();//XMLHttpRequest
- }
-
- // Content-Type: text/html;charset:utf-8;
-
- /**
- *
- * @author wchao
- * 2017年6月27日 下午8:23:58
- */
- public interface RequestHeaderValue {
- public interface Connection {
- String keep_alive = "keep-alive".toLowerCase();
- String Upgrade = "Upgrade".toLowerCase();
- String close = "close".toLowerCase();
- }
-
- //application/x-www-form-urlencoded、multipart/form-data、text/plain
- public interface Content_Type {
- /**
- * 普通文本,一般会是json或是xml
- */
- String text_plain = "text/plain".toLowerCase();
- /**
- * 文件上传
- */
- String multipart_form_data = "multipart/form-data".toLowerCase();
- /**
- * 普通的key-value
- */
- String application_x_www_form_urlencoded = "application/x-www-form-urlencoded".toLowerCase();
- }
- }
-
- public interface ResponseHeaderKey {
- //Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
- String Set_Cookie = "Set-Cookie".toLowerCase(); //Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
- String Content_Length = "Content-Length".toLowerCase(); //65
-
- String Connection = "Connection".toLowerCase(); //Upgrade, keep-alive
- String Keep_Alive = "Keep-Alive".toLowerCase(); //Keep-Alive:timeout=20
- String Sec_WebSocket_Accept = "Sec-WebSocket-Accept".toLowerCase();
- String Upgrade = "Upgrade".toLowerCase();
-
- /**
- * Content-Disposition: attachment;filename=FileName.txt
- * 文件下载
- */
- String Content_disposition = "Content-disposition".toLowerCase();
- /**
- * 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。
- * 利用gzip压缩文档能够显著地减少HTML文档的下载时间。
- * Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。
- * 因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,
- * 为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
- */
- String Content_Encoding = "Content-Encoding".toLowerCase();
- /**
- * 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。
- * 由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
- */
- String Content_Type = "Content-Type".toLowerCase();
- /**
- * 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
- */
- String Date = "Date".toLowerCase();
- /**
- * 应该在什么时候认为文档已经过期,从而不再缓存它?
- */
- String Expires = "Expires".toLowerCase();
- /**
- * 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,
- * 只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
- */
- String Last_Modified = "Last-Modified".toLowerCase();
- /**
- * 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
- */
- String Location = "Location".toLowerCase();
- /**
- * 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。
- 注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。
-
- 注意Refresh的意义是"N秒之后刷新本页面或访问指定页面",而不是"每隔N秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。
-
- 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
- */
- String Refresh = "Refresh".toLowerCase();
- /**
- * 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
- */
- String Server = "Server".toLowerCase();
-
- /**
- *
- */
- String Access_Control_Allow_Origin = "Access-Control-Allow-Origin".toLowerCase(); //value: *
-
- /**
- *
- */
- String Access_Control_Allow_Headers = "Access-Control-Allow-Headers".toLowerCase(); //value: x-requested-with,content-type
-
- /**
- * 是否是从缓存中获取的数据,tio-httpserver特有的头部信息
- */
- String tio_from_cache = "tio-from-cache";
- }
-
- /**
- *
- * @author wchao
- * 2017年6月27日 下午8:24:02
- */
- public interface ResponseHeaderValue {
- public interface Connection {
- String keep_alive = "keep-alive".toLowerCase();
- String Upgrade = "Upgrade".toLowerCase();
- String close = "close".toLowerCase();
- }
- }
-
- /**
- *
- */
- String SERVER_INFO = "tio-httpserver/0.0.1";
-
- /**
- * 默认规定连接到本服务器的客户端统一用utf-8
- */
- String CHARSET_NAME = "utf-8";
}
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpConvertPacket.java b/jim-common/src/main/java/org/jim/common/http/HttpConvertPacket.java
index c3ffbec..870dfb6 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpConvertPacket.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpConvertPacket.java
@@ -3,26 +3,26 @@
*/
package org.jim.common.http;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
+import org.jim.common.ImSessionContext;
import org.jim.common.http.session.HttpSession;
import org.jim.common.packets.Command;
-import org.jim.common.protocol.IConvertProtocolPacket;
-import org.tio.core.ChannelContext;
-
+import org.jim.common.protocol.IProtocolConverter;
/**
* HTTP协议消息转化包
* @author WChao
*
*/
-public class HttpConvertPacket implements IConvertProtocolPacket {
+public class HttpConvertPacket implements IProtocolConverter {
/**
* 转HTTP协议响应包;
*/
@Override
- public ImPacket RespPacket(byte[] body, Command command,ChannelContext channelContext) {
- Object sessionContext = channelContext.getAttribute();
+ public ImPacket RespPacket(byte[] body, Command command, ImChannelContext channelContext) {
+ ImSessionContext sessionContext = channelContext.getSessionContext();
if(sessionContext instanceof HttpSession){
HttpRequest request = (HttpRequest)channelContext.getAttribute(ImConst.HTTP_REQUEST);
HttpResponse response = new HttpResponse(request,request.getHttpConfig());
@@ -34,7 +34,7 @@ public class HttpConvertPacket implements IConvertProtocolPacket {
}
@Override
- public ImPacket ReqPacket(byte[] body, Command command,ChannelContext channelContext) {
+ public ImPacket ReqPacket(byte[] body, Command command, ImChannelContext channelContext) {
return null;
}
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpMultiBodyDecoder.java b/jim-common/src/main/java/org/jim/common/http/HttpMultiBodyDecoder.java
index 5213288..5d86658 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpMultiBodyDecoder.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpMultiBodyDecoder.java
@@ -8,10 +8,10 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
+import org.jim.common.ImChannelContext;
+import org.jim.common.exception.ImDecodeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
import org.tio.core.exception.LengthOverflowException;
import org.tio.core.utils.ByteBufferUtils;
import org.jim.common.utils.HttpParseUtils;
@@ -83,31 +83,20 @@ public class HttpMultiBodyDecoder {
* @author wchao
* 2017年7月27日 上午10:18:01
*/
- public static interface MultiBodyHeaderKey {
+ public interface MultiBodyHeaderKey {
String Content_Disposition = "Content-Disposition".toLowerCase();
String Content_Type = "Content-Type".toLowerCase();
}
- public static enum Step {
+ public enum Step {
BOUNDARY, HEADER, BODY, END
}
private static Logger log = LoggerFactory.getLogger(HttpMultiBodyDecoder.class);
- // public static int processReadIndex(ByteBuffer buffer)
- // {
- // int newReaderIndex = buffer.readerIndex();
- // if (newReaderIndex < buffer.capacity())
- // {
- // buffer.readerIndex(newReaderIndex + 1);
- // return 1;
- // }
- // return 0;
- // }
-
- public static void decode(HttpRequest request, RequestLine firstLine, byte[] bodyBytes, String initboundary, ChannelContext channelContext) throws AioDecodeException {
- if (StringUtils.isBlank(initboundary)) {
- throw new AioDecodeException("boundary is null");
+ public static void decode(HttpRequest request, RequestLine firstLine, byte[] bodyBytes, String initBoundary, ImChannelContext channelContext) throws ImDecodeException {
+ if (StringUtils.isBlank(initBoundary)) {
+ throw new ImDecodeException("boundary is null");
}
long start = SystemTimer.currentTimeMillis();
@@ -115,25 +104,21 @@ public class HttpMultiBodyDecoder {
ByteBuffer buffer = ByteBuffer.wrap(bodyBytes);
buffer.position(0);
- String boundary = "--" + initboundary;
+ String boundary = "--" + initBoundary;
String endBoundary = boundary + "--";
-
- // int boundaryLength = boundary.getBytes().length;
Step step = Step.BOUNDARY;
- // int bufferLength = buffer.capacity();
try {
label1: while (true) {
if (step == Step.BOUNDARY) {
String line = ByteBufferUtils.readLine(buffer, request.getCharset(), HttpConfig.MAX_LENGTH_OF_BOUNDARY);
- // int offset = HttpMultiBodyDecoder.processReadIndex(buffer);
if (boundary.equals(line)) {
step = Step.HEADER;
- } else if (endBoundary.equals(line)) // 结束了
+ // 结束了
+ } else if (endBoundary.equals(line))
{
- // int ss = buffer.readerIndex() + 2 - offset;
break;
} else {
- throw new AioDecodeException("line need:" + boundary + ", but is: " + line + "");
+ throw new ImDecodeException("line need:" + boundary + ", but is: " + line + "");
}
}
@@ -164,7 +149,7 @@ public class HttpMultiBodyDecoder {
}
} catch (LengthOverflowException loe) {
- throw new AioDecodeException(loe);
+ throw new ImDecodeException(loe);
} catch (UnsupportedEncodingException e) {
log.error(channelContext.toString(), e);
} finally {
@@ -175,37 +160,6 @@ public class HttpMultiBodyDecoder {
}
- /**
- * 返回值不包括最后的\r\n
- * @param buffer
- * @param charset
- * @return
- * @throws UnsupportedEncodingException
- */
- // public static String getLine(ByteBuffer buffer, String charset) throws UnsupportedEncodingException {
- // char lastByte = 0; // 上一个字节
- // int initPosition = buffer.position();
- //
- // while (buffer.hasRemaining()) {
- // char b = (char) buffer.get();
- //
- // if (b == '\n') {
- // if (lastByte == '\r') {
- // int startIndex = initPosition;
- // int endIndex = buffer.position() - 2;
- // int length = endIndex - startIndex;
- // byte[] dst = new byte[length];
- //
- // System.arraycopy(buffer.array(), startIndex, dst, 0, length);
- // String line = new String(dst, charset);
- // return line;
- // }
- // }
- // lastByte = b;
- // }
- // return null;
- // }
-
/**
* @param args
* @throws UnsupportedEncodingException
@@ -234,7 +188,7 @@ public class HttpMultiBodyDecoder {
* @throws LengthOverflowException
* @author wchao
*/
- public static Step parseBody(Header header, HttpRequest request, ByteBuffer buffer, String boundary, String endBoundary, ChannelContext channelContext)
+ public static Step parseBody(Header header, HttpRequest request, ByteBuffer buffer, String boundary, String endBoundary, ImChannelContext channelContext)
throws UnsupportedEncodingException, LengthOverflowException {
int initPosition = buffer.position();
@@ -249,10 +203,11 @@ public class HttpMultiBodyDecoder {
byte[] dst = new byte[length];
System.arraycopy(buffer.array(), startIndex, dst, 0, length);
+ //该字段类型是file
String filename = header.getFilename();
- if (filename != null)//该字段类型是file
+ if (filename != null)
{
- if (!"".equals(filename)) { //
+ if (!"".equals(filename)) {
UploadFile uploadFile = new UploadFile();
uploadFile.setName(filename);
uploadFile.setData(dst);
@@ -285,24 +240,22 @@ public class HttpMultiBodyDecoder {
* @param header
* @author wchao
*/
- public static void parseHeader(List lines, Header header, ChannelContext channelContext) throws AioDecodeException {
+ public static void parseHeader(List lines, Header header, ImChannelContext channelContext) throws ImDecodeException {
if (lines == null || lines.size() == 0) {
- throw new AioDecodeException("multipart_form_data 格式不对,没有头部信息");
+ throw new ImDecodeException("multipart_form_data 格式不对,没有头部信息");
}
-
try {
for (String line : lines) {
- String[] keyvalue = StringUtils.split(line, ":");
- String key = StringUtils.lowerCase(StringUtils.trim(keyvalue[0]));//
- String value = StringUtils.trim(keyvalue[1]);
+ String[] keyValue = StringUtils.split(line, ":");
+ String key = StringUtils.lowerCase(StringUtils.trim(keyValue[0]));
+ String value = StringUtils.trim(keyValue[1]);
header.map.put(key, value);
}
String contentDisposition = header.map.get(MultiBodyHeaderKey.Content_Disposition);
String name = HttpParseUtils.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Disposition, "name");
String filename = HttpParseUtils.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Disposition, "filename");
- String contentType = header.map.get(MultiBodyHeaderKey.Content_Type);//.HttpParseUtils.getPerprotyEqualValue(header.map, MultiBodyHeaderKey.Content_Type, "filename");
-
+ String contentType = header.map.get(MultiBodyHeaderKey.Content_Type);
header.setContentDisposition(contentDisposition);
header.setName(name);
header.setFilename(filename);
@@ -310,29 +263,8 @@ public class HttpMultiBodyDecoder {
} catch (Exception e) {
log.error(channelContext.toString(), e);
- throw new AioDecodeException(e.toString());
+ throw new ImDecodeException(e.toString());
}
-
- // for (int i = 0; i < lines.size(); i++) {
- // String line = lines.get(i);
- // if (i == 0) {
- // String[] mapStrings = StringUtils.split(line, ";");
- // String s = mapStrings[0];//
- //
- // String[] namekeyvalue = StringUtils.split(mapStrings[1], "=");
- // header.setName(namekeyvalue[1].substring(1, namekeyvalue[1].length() - 1));
- //
- // if (mapStrings.length == 3) {
- // String[] finenamekeyvalue = StringUtils.split(mapStrings[2], "=");
- // String filename = finenamekeyvalue[1].substring(1, finenamekeyvalue[1].length() - 1);
- // header.setFilename(FilenameUtils.getName(filename));
- // }
- // } else if (i == 1) {
- // String[] map = StringUtils.split(line, ":");
- // String contentType = map[1].trim();//
- // header.setContentType(contentType);
- // }
- // }
}
/**
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpProtocol.java b/jim-common/src/main/java/org/jim/common/http/HttpProtocol.java
index c2097b7..955f281 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpProtocol.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpProtocol.java
@@ -4,62 +4,58 @@
package org.jim.common.http;
import java.nio.ByteBuffer;
-
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.jim.common.ImSessionContext;
-import org.jim.common.Protocol;
+import org.jim.common.exception.ImException;
import org.jim.common.http.session.HttpSession;
-import org.jim.common.protocol.AbProtocol;
-import org.jim.common.protocol.IConvertProtocolPacket;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.protocol.IProtocolConverter;
import org.jim.common.utils.ImUtils;
-import org.tio.core.ChannelContext;
-
/**
*
* Http协议校验器
* @author WChao
*
*/
-public class HttpProtocol extends AbProtocol {
+public class HttpProtocol extends AbstractProtocol {
@Override
public String name() {
return Protocol.HTTP;
}
+ public HttpProtocol(IProtocolConverter protocolConverter){
+ super(protocolConverter);
+ }
+
@Override
- public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- if(imSessionContext != null && imSessionContext instanceof HttpSession) {
+ protected void init(ImChannelContext imChannelContext) {
+ imChannelContext.setSessionContext(new HttpSession(imChannelContext));
+ ImUtils.setClient(imChannelContext);
+ }
+
+ @Override
+ public boolean validateProtocol(ImSessionContext imSessionContext) throws ImException {
+ if(imSessionContext instanceof HttpSession) {
return true;
}
- if(buffer != null){
- HttpRequest request = HttpRequestDecoder.decode(buffer, channelContext,false);
- if(request.getHeaders().get(HttpConst.RequestHeaderKey.Sec_WebSocket_Key) == null)
- {
- channelContext.setAttribute(new HttpSession());
- ImUtils.setClient(channelContext);
- return true;
- }
- }
return false;
}
@Override
- public IConvertProtocolPacket converter() {
- return new HttpConvertPacket();
+ public boolean validateProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException {
+ HttpRequest request = HttpRequestDecoder.decode(buffer, imChannelContext,false);
+ if(request.getHeaders().get(Http.RequestHeaderKey.Sec_WebSocket_Key) == null)
+ {
+ return true;
+ }
+ return false;
}
@Override
- public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
- if(imPacket == null) {
- return false;
- }
+ public boolean validateProtocol(ImPacket imPacket) throws ImException {
if(imPacket instanceof HttpPacket){
- Object sessionContext = channelContext.getAttribute();
- if(sessionContext == null){
- channelContext.setAttribute(new HttpSession());
- }
return true;
}
return false;
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpRequest.java b/jim-common/src/main/java/org/jim/common/http/HttpRequest.java
index 93677f4..f24aee0 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpRequest.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpRequest.java
@@ -7,12 +7,13 @@ import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.Node;
-import org.jim.common.http.HttpConst.RequestBodyFormat;
import org.jim.common.http.session.HttpSession;
+import org.tio.utils.hutool.ArrayUtil;
-import cn.hutool.core.util.ArrayUtil;
/**
*
* @author wchao
@@ -20,7 +21,7 @@ import cn.hutool.core.util.ArrayUtil;
*/
public class HttpRequest extends HttpPacket {
- // private static Logger log = LoggerFactory.getLogger(HttpRequest.class);
+ private static Logger log = LoggerFactory.getLogger(HttpRequest.class);
private static final long serialVersionUID = -3849253977016967211L;
@@ -43,14 +44,12 @@ public class HttpRequest extends HttpPacket {
private Map cookieMap = null;
private int contentLength;
private String bodyString;
- private RequestBodyFormat bodyFormat;
- private String charset = HttpConst.CHARSET_NAME;
+ private Http.RequestBodyFormat bodyFormat;
+ private String charset = Http.CHARSET_NAME;
private Boolean isAjax = null;
private Boolean isSupportGzip = null;
private HttpSession httpSession;
- private Node remote = null;
- private ChannelContext channelContext;
-
+ private Node remote;
private HttpConfig httpConfig;
/**
@@ -84,7 +83,7 @@ public class HttpRequest extends HttpPacket {
/**
* @return the bodyFormat
*/
- public RequestBodyFormat getBodyFormat() {
+ public Http.RequestBodyFormat getBodyFormat() {
return bodyFormat;
}
@@ -95,13 +94,6 @@ public class HttpRequest extends HttpPacket {
return bodyString;
}
- /**
- * @return the channelContext
- */
- public ChannelContext getChannelContext() {
- return channelContext;
- }
-
/**
* @return the charset
*/
@@ -156,7 +148,7 @@ public class HttpRequest extends HttpPacket {
*/
public Boolean getIsAjax() {
if (isAjax == null) {
- String X_Requested_With = this.getHeader(HttpConst.RequestHeaderKey.X_Requested_With);
+ String X_Requested_With = this.getHeader(Http.RequestHeaderKey.X_Requested_With);
if (X_Requested_With != null && "XMLHttpRequest".equalsIgnoreCase(X_Requested_With)) {
isAjax = true;
} else {
@@ -172,7 +164,7 @@ public class HttpRequest extends HttpPacket {
*/
public Boolean getIsSupportGzip() {
if (isSupportGzip == null) {
- String Accept_Encoding = getHeader(HttpConst.RequestHeaderKey.Accept_Encoding);
+ String Accept_Encoding = getHeader(Http.RequestHeaderKey.Accept_Encoding);
if (StringUtils.isNoneBlank(Accept_Encoding)) {
String[] ss = StringUtils.split(Accept_Encoding, ",");
if (ArrayUtil.contains(ss, "gzip")) {
@@ -219,7 +211,7 @@ public class HttpRequest extends HttpPacket {
}
public void parseCookie() {
- String cookieLine = headers.get(HttpConst.RequestHeaderKey.Cookie);
+ String cookieLine = headers.get(Http.RequestHeaderKey.Cookie);
if (StringUtils.isNotBlank(cookieLine)) {
cookies = new ArrayList<>();
cookieMap = new HashMap<>();
@@ -233,7 +225,7 @@ public class HttpRequest extends HttpPacket {
Cookie cookie = Cookie.buildCookie(cookieOneMap);
cookies.add(cookie);
cookieMap.put(cookie.getName(), cookie);
- //log.error("{}, 收到cookie:{}", channelContext, cookie.toString());
+ log.info("{}, 收到cookie:{}", imChannelContext, cookie.toString());
}
}
}
@@ -241,7 +233,7 @@ public class HttpRequest extends HttpPacket {
/**
* @param bodyFormat the bodyFormat to set
*/
- public void setBodyFormat(RequestBodyFormat bodyFormat) {
+ public void setBodyFormat(Http.RequestBodyFormat bodyFormat) {
this.bodyFormat = bodyFormat;
}
@@ -252,13 +244,6 @@ public class HttpRequest extends HttpPacket {
this.bodyString = bodyString;
}
- /**
- * @param channelContext the channelContext to set
- */
- public void setChannelContext(ChannelContext channelContext) {
- this.channelContext = channelContext;
- }
-
/**
* @param charset the charset to set
*/
@@ -267,7 +252,7 @@ public class HttpRequest extends HttpPacket {
}
/**
- * @param bodyLength the bodyLength to set
+ * @param contentLength the bodyLength to set
*/
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
@@ -290,7 +275,6 @@ public class HttpRequest extends HttpPacket {
/**
* 设置好header后,会把cookie等头部信息也设置好
* @param headers the headers to set
- * @param channelContext
*/
@Override
public void setHeaders(Map headers) {
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpRequestDecoder.java b/jim-common/src/main/java/org/jim/common/http/HttpRequestDecoder.java
index d0b5262..ed5a82c 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpRequestDecoder.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpRequestDecoder.java
@@ -7,24 +7,23 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.http.HttpConst.RequestBodyFormat;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.exception.ImDecodeException;
import org.jim.common.utils.HttpParseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
import org.tio.core.exception.LengthOverflowException;
import org.tio.core.utils.ByteBufferUtils;
-
-import cn.hutool.core.util.StrUtil;
+import org.tio.utils.hutool.StrUtil;
/**
*
* @author WChao
*
*/
-public class HttpRequestDecoder {
- public static enum Step {
+public class HttpRequestDecoder implements ImConst {
+ public enum Step {
firstLine, header, body
}
@@ -40,7 +39,7 @@ public class HttpRequestDecoder {
*/
public static final int MAX_LENGTH_OF_HEADER_LINE = 2048;
- public static HttpRequest decode(ByteBuffer buffer, ChannelContext channelContext,boolean isBody) throws AioDecodeException {
+ public static HttpRequest decode(ByteBuffer buffer, ImChannelContext channelContext, boolean isBody) throws ImDecodeException {
int initPosition = buffer.position();
int readableLength = buffer.limit() - initPosition;
// int count = 0;
@@ -48,7 +47,7 @@ public class HttpRequestDecoder {
// StringBuilder currLine = new StringBuilder();
Map headers = new HashMap<>();
int contentLength = 0;
- byte[] bodyBytes = null;
+ byte[] bodyBytes;
StringBuilder headerSb = new StringBuilder(512);
RequestLine firstLine = null;
@@ -57,12 +56,12 @@ public class HttpRequestDecoder {
try {
line = ByteBufferUtils.readLine(buffer, null, MAX_LENGTH_OF_HEADER_LINE);
} catch (LengthOverflowException e) {
- throw new AioDecodeException(e);
+ throw new ImDecodeException(e);
}
int newPosition = buffer.position();
if (newPosition - initPosition > MAX_LENGTH_OF_HEADER) {
- throw new AioDecodeException("max http header length " + MAX_LENGTH_OF_HEADER);
+ throw new ImDecodeException("max http header length " + MAX_LENGTH_OF_HEADER);
}
if (line == null) {
@@ -72,7 +71,7 @@ public class HttpRequestDecoder {
headerSb.append(line).append("\r\n");
//头部解析完成了
if ("".equals(line) && isBody) {
- String contentLengthStr = headers.get(HttpConst.RequestHeaderKey.Content_Length);
+ String contentLengthStr = headers.get(Http.RequestHeaderKey.Content_Length);
if (StringUtils.isBlank(contentLengthStr)) {
contentLength = 0;
} else {
@@ -109,13 +108,13 @@ public class HttpRequestDecoder {
return null;
}
- if (!headers.containsKey(HttpConst.RequestHeaderKey.Host)) {
- throw new AioDecodeException("there is no host header");
+ if (!headers.containsKey(Http.RequestHeaderKey.Host)) {
+ throw new ImDecodeException("there is no host header");
}
HttpRequest httpRequest = new HttpRequest(channelContext.getClientNode());
- httpRequest.setChannelContext(channelContext);
- httpRequest.setHttpConfig((HttpConfig) channelContext.getGroupContext().getAttribute(GroupContextKey.HTTP_SERVER_CONFIG));
+ httpRequest.setImChannelContext(channelContext);
+ httpRequest.setHttpConfig((HttpConfig) channelContext.getAttribute(Key.HTTP_SERVER_CONFIG));
httpRequest.setHeaderString(headerSb.toString());
httpRequest.setRequestLine(firstLine);
httpRequest.setHeaders(headers);
@@ -136,7 +135,7 @@ public class HttpRequestDecoder {
}
- public static void decodeParams(Map params, String paramsStr, String charset, ChannelContext channelContext) {
+ public static void decodeParams(Map params, String paramsStr, String charset, ImChannelContext channelContext) {
if (StrUtil.isBlank(paramsStr)) {
return;
}
@@ -175,18 +174,18 @@ public class HttpRequestDecoder {
* @param firstLine
* @param bodyBytes
* @param channelContext
- * @throws AioDecodeException
+ * @throws ImDecodeException
* @author WChao
*/
- private static void parseBody(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, ChannelContext channelContext) throws AioDecodeException {
+ private static void parseBody(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, ImChannelContext channelContext) throws ImDecodeException {
parseBodyFormat(httpRequest, httpRequest.getHeaders());
- RequestBodyFormat bodyFormat = httpRequest.getBodyFormat();
+ Http.RequestBodyFormat bodyFormat = httpRequest.getBodyFormat();
httpRequest.setBody(bodyBytes);
- if (bodyFormat == RequestBodyFormat.MULTIPART) {
+ if (bodyFormat == Http.RequestBodyFormat.MULTIPART) {
if (log.isInfoEnabled()) {
- String bodyString = null;
+ String bodyString;
if (bodyBytes != null && bodyBytes.length > 0) {
if (log.isDebugEnabled()) {
try {
@@ -200,7 +199,7 @@ public class HttpRequestDecoder {
}
//【multipart/form-data; boundary=----WebKitFormBoundaryuwYcfA2AIgxqIxA0】
- String initBoundary = HttpParseUtils.getPerprotyEqualValue(httpRequest.getHeaders(), HttpConst.RequestHeaderKey.Content_Type, "boundary");
+ String initBoundary = HttpParseUtils.getPerprotyEqualValue(httpRequest.getHeaders(), Http.RequestHeaderKey.Content_Type, "boundary");
log.debug("{}, initBoundary:{}", channelContext, initBoundary);
HttpMultiBodyDecoder.decode(httpRequest, firstLine, bodyBytes, initBoundary, channelContext);
} else {
@@ -217,7 +216,7 @@ public class HttpRequestDecoder {
}
}
- if (bodyFormat == RequestBodyFormat.URLENCODED) {
+ if (bodyFormat == Http.RequestBodyFormat.URLENCODED) {
parseUrlencoded(httpRequest, firstLine, bodyBytes, bodyString, channelContext);
}
}
@@ -231,19 +230,19 @@ public class HttpRequestDecoder {
* @author WChao
*/
public static void parseBodyFormat(HttpRequest httpRequest, Map headers) {
- String Content_Type = StringUtils.lowerCase(headers.get(HttpConst.RequestHeaderKey.Content_Type));
- RequestBodyFormat bodyFormat = null;
- if (StringUtils.contains(Content_Type, HttpConst.RequestHeaderValue.Content_Type.application_x_www_form_urlencoded)) {
- bodyFormat = RequestBodyFormat.URLENCODED;
- } else if (StringUtils.contains(Content_Type, HttpConst.RequestHeaderValue.Content_Type.multipart_form_data)) {
- bodyFormat = RequestBodyFormat.MULTIPART;
+ String Content_Type = StringUtils.lowerCase(headers.get(Http.RequestHeaderKey.Content_Type));
+ Http.RequestBodyFormat bodyFormat;
+ if (StringUtils.contains(Content_Type, Http.RequestHeaderValue.Content_Type.application_x_www_form_urlencoded)) {
+ bodyFormat = Http.RequestBodyFormat.URLENCODED;
+ } else if (StringUtils.contains(Content_Type, Http.RequestHeaderValue.Content_Type.multipart_form_data)) {
+ bodyFormat = Http.RequestBodyFormat.MULTIPART;
} else {
- bodyFormat = RequestBodyFormat.TEXT;
+ bodyFormat = Http.RequestBodyFormat.TEXT;
}
httpRequest.setBodyFormat(bodyFormat);
if (StringUtils.isNotBlank(Content_Type)) {
- String charset = HttpParseUtils.getPerprotyEqualValue(headers, HttpConst.RequestHeaderKey.Content_Type, "charset");
+ String charset = HttpParseUtils.getPerprotyEqualValue(headers, Http.RequestHeaderKey.Content_Type, "charset");
if (StringUtils.isNotBlank(charset)) {
httpRequest.setCharset(charset);
}
@@ -284,7 +283,7 @@ public class HttpRequestDecoder {
* 2017年2月23日 下午1:37:51
*
*/
- public static RequestLine parseRequestLine(String line, ChannelContext channelContext) throws AioDecodeException {
+ public static RequestLine parseRequestLine(String line, ImChannelContext channelContext) throws ImDecodeException {
try {
int index1 = line.indexOf(' ');
String _method = StringUtils.upperCase(line.substring(0, index1));
@@ -322,7 +321,7 @@ public class HttpRequestDecoder {
return requestLine;
} catch (Throwable e) {
log.error(channelContext.toString(), e);
- throw new AioDecodeException(e);
+ throw new ImDecodeException(e);
}
}
@@ -331,7 +330,7 @@ public class HttpRequestDecoder {
* 形如: 【Content-Type : application/x-www-form-urlencoded; charset=UTF-8】
* @author WChao
*/
- private static void parseUrlencoded(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, String bodyString, ChannelContext channelContext) {
+ private static void parseUrlencoded(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, String bodyString, ImChannelContext channelContext) {
if (StringUtils.isNotBlank(bodyString)) {
decodeParams(httpRequest.getParams(), bodyString, httpRequest.getCharset(), channelContext);
}
@@ -343,7 +342,7 @@ public class HttpRequestDecoder {
* @param firstLine
* @param channelContext
*/
- private static void parseQueryString(HttpRequest httpRequest, RequestLine firstLine, ChannelContext channelContext) {
+ private static void parseQueryString(HttpRequest httpRequest, RequestLine firstLine, ImChannelContext channelContext) {
String paramStr = firstLine.getQuery();
if (StringUtils.isNotBlank(paramStr)) {
decodeParams(httpRequest.getParams(), paramStr, httpRequest.getCharset(), channelContext);
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpResponse.java b/jim-common/src/main/java/org/jim/common/http/HttpResponse.java
index 6d08dfc..c438582 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpResponse.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpResponse.java
@@ -2,12 +2,11 @@ package org.jim.common.http;
import java.util.ArrayList;
import java.util.List;
-
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.tio.utils.hutool.ZipUtil;
-import cn.hutool.core.util.ZipUtil;
/**
*
* @author WChao
@@ -36,12 +35,11 @@ public class HttpResponse extends HttpPacket {
*/
private boolean isStaticRes = false;
- private HttpRequest request = null;
+ private HttpRequest request;
+
private volatile List cookies = null;
- // private int contentLength;
- // private byte[] bodyBytes;
- private String charset = HttpConst.CHARSET_NAME;
+ private String charset = Http.CHARSET_NAME;
/**
* 已经编码好的byte[]
@@ -57,29 +55,29 @@ public class HttpResponse extends HttpPacket {
public HttpResponse(HttpRequest request, HttpConfig httpConfig) {
this.request = request;
- String Connection = StringUtils.lowerCase(request.getHeader(HttpConst.RequestHeaderKey.Connection));
+ String Connection = StringUtils.lowerCase(request.getHeader(Http.RequestHeaderKey.Connection));
RequestLine requestLine = request.getRequestLine();
String version = requestLine.getVersion();
if ("1.0".equals(version)) {
- if (StringUtils.equals(Connection, HttpConst.RequestHeaderValue.Connection.keep_alive)) {
- addHeader(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.keep_alive);
- addHeader(HttpConst.ResponseHeaderKey.Keep_Alive, "timeout=10, max=20");
+ if (StringUtils.equals(Connection, Http.RequestHeaderValue.Connection.keep_alive)) {
+ addHeader(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.keep_alive);
+ addHeader(Http.ResponseHeaderKey.Keep_Alive, "timeout=10, max=20");
} else {
- addHeader(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.close);
+ addHeader(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.close);
}
} else {
- if (StringUtils.equals(Connection, HttpConst.RequestHeaderValue.Connection.close)) {
- addHeader(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.close);
+ if (StringUtils.equals(Connection, Http.RequestHeaderValue.Connection.close)) {
+ addHeader(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.close);
} else {
- addHeader(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.keep_alive);
- addHeader(HttpConst.ResponseHeaderKey.Keep_Alive, "timeout=10, max=20");
+ addHeader(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.keep_alive);
+ addHeader(Http.ResponseHeaderKey.Keep_Alive, "timeout=10, max=20");
}
}
//暂时先设置为短连接...防止服务器一直不释放资源;
- addHeader(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.close);
+ addHeader(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.close);
if (httpConfig != null) {
- addHeader(HttpConst.ResponseHeaderKey.Server, httpConfig.getServerInfo());
+ addHeader(Http.ResponseHeaderKey.Server, httpConfig.getServerInfo());
}
}
@@ -137,11 +135,11 @@ public class HttpResponse extends HttpPacket {
byte[] bs2 = ZipUtil.gzip(bs);
if (bs2.length < bs.length) {
this.body = bs2;
- this.addHeader(HttpConst.ResponseHeaderKey.Content_Encoding, "gzip");
+ this.addHeader(Http.ResponseHeaderKey.Content_Encoding, "gzip");
}
}
} else {
- log.info("{} 竟然不支持gzip, {}", request.getChannelContext(), request.getHeader(HttpConst.RequestHeaderKey.User_Agent));
+ log.info("{} 竟然不支持gzip, {}", request.getImChannelContext(), request.getHeader(Http.RequestHeaderKey.User_Agent));
}
}
diff --git a/jim-common/src/main/java/org/jim/common/http/HttpResponseEncoder.java b/jim-common/src/main/java/org/jim/common/http/HttpResponseEncoder.java
index e9b4337..f985b94 100644
--- a/jim-common/src/main/java/org/jim/common/http/HttpResponseEncoder.java
+++ b/jim-common/src/main/java/org/jim/common/http/HttpResponseEncoder.java
@@ -6,18 +6,18 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-
/**
*
* @author wchao
* 2017年8月4日 上午9:41:12
*/
-public class HttpResponseEncoder {
- public static enum Step {
+public class HttpResponseEncoder implements ImConst {
+ public enum Step {
firstLine, header, body
}
@@ -28,13 +28,12 @@ public class HttpResponseEncoder {
/**
*
* @param httpResponse
- * @param groupContext
* @param channelContext
* @param skipCookie true: 忽略掉cookie部分的编码
* @return
- * @author wchao
+ * @author WChao
*/
- public static ByteBuffer encode(HttpResponse httpResponse, GroupContext groupContext, ChannelContext channelContext, boolean skipCookie) {
+ public static ByteBuffer encode(HttpResponse httpResponse, ImChannelContext channelContext, boolean skipCookie) {
byte[] encodedBytes = httpResponse.getEncodedBytes();
if (encodedBytes != null) {
ByteBuffer ret = ByteBuffer.wrap(encodedBytes);
@@ -56,7 +55,7 @@ public class HttpResponseEncoder {
Map headers = httpResponse.getHeaders();
if (headers != null && headers.size() > 0) {
- headers.put(HttpConst.ResponseHeaderKey.Content_Length, bodyLength + "");
+ headers.put(Http.ResponseHeaderKey.Content_Length, bodyLength + "");
Set> set = headers.entrySet();
for (Entry entry : set) {
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
@@ -68,7 +67,7 @@ public class HttpResponseEncoder {
List cookies = httpResponse.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
- sb.append(HttpConst.ResponseHeaderKey.Set_Cookie).append(": ");
+ sb.append(Http.ResponseHeaderKey.Set_Cookie).append(": ");
sb.append(cookie.toString());
sb.append("\r\n");
if (log.isInfoEnabled()) {
diff --git a/jim-common/src/main/java/org/jim/common/http/handler/IHttpRequestHandler.java b/jim-common/src/main/java/org/jim/common/http/handler/IHttpRequestHandler.java
index 1c81351..b1455a9 100644
--- a/jim-common/src/main/java/org/jim/common/http/handler/IHttpRequestHandler.java
+++ b/jim-common/src/main/java/org/jim/common/http/handler/IHttpRequestHandler.java
@@ -1,5 +1,6 @@
package org.jim.common.http.handler;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpResponse;
import org.jim.common.http.RequestLine;
@@ -15,16 +16,15 @@ public interface IHttpRequestHandler {
* @param packet
* @param requestLine
* @return
- * @throws Exception
+ * @throws ImException
* @author wchao
*/
- public HttpResponse handler(HttpRequest packet, RequestLine requestLine) throws Exception;
+ public HttpResponse handler(HttpRequest packet, RequestLine requestLine) throws ImException;
/**
*
* @param request
* @param requestLine
- * @param channelContext
* @return
* @author wchao
*/
diff --git a/jim-common/src/main/java/org/jim/common/http/session/HttpSession.java b/jim-common/src/main/java/org/jim/common/http/session/HttpSession.java
index 680b876..b15ffe6 100644
--- a/jim-common/src/main/java/org/jim/common/http/session/HttpSession.java
+++ b/jim-common/src/main/java/org/jim/common/http/session/HttpSession.java
@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImSessionContext;
import org.jim.common.http.HttpConfig;
@@ -18,15 +19,16 @@ public class HttpSession extends ImSessionContext implements java.io.Serializabl
private Map data = new ConcurrentHashMap<>();
- private String id = null;
-
- public HttpSession() {
+ public HttpSession(String id){
+ this(id, null);
}
- /**
- * @author wchao
- */
- public HttpSession(String id) {
+ public HttpSession(ImChannelContext imChannelContext){
+ this(null, imChannelContext);
+ }
+
+ public HttpSession(String id, ImChannelContext imChannelContext){
+ super(imChannelContext);
this.id = id;
}
diff --git a/jim-common/src/main/java/org/jim/common/listener/AbstractImBindListener.java b/jim-common/src/main/java/org/jim/common/listener/AbstractImBindListener.java
index 410347a..81ce5eb 100644
--- a/jim-common/src/main/java/org/jim/common/listener/AbstractImBindListener.java
+++ b/jim-common/src/main/java/org/jim/common/listener/AbstractImBindListener.java
@@ -4,7 +4,7 @@
package org.jim.common.listener;
import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
+import org.jim.common.config.ImConfig;
/**
* @author WChao
* 2018/08/26
diff --git a/jim-common/src/main/java/org/jim/common/listener/ImBindListener.java b/jim-common/src/main/java/org/jim/common/listener/ImBindListener.java
index 17714da..c06a9e9 100644
--- a/jim-common/src/main/java/org/jim/common/listener/ImBindListener.java
+++ b/jim-common/src/main/java/org/jim/common/listener/ImBindListener.java
@@ -1,6 +1,7 @@
package org.jim.common.listener;
-import org.tio.core.ChannelContext;
+import org.jim.common.ImChannelContext;
+import org.jim.common.exception.ImException;
/**
* IM绑定用户及群组监听器;
@@ -10,39 +11,39 @@ import org.tio.core.ChannelContext;
public interface ImBindListener {
/**
* 绑定群组后回调该方法
- * @param channelContext
+ * @param imChannelContext
* @param group
* @throws Exception
*/
- void onAfterGroupBind(ChannelContext channelContext, String group) throws Exception;
+ void onAfterGroupBind(ImChannelContext imChannelContext, String group) throws ImException;
/**
* 解绑群组后回调该方法
- * @param channelContext
+ * @param imChannelContext
* @param group
* @throws Exception
*/
- void onAfterGroupUnbind(ChannelContext channelContext, String group) throws Exception;
+ void onAfterGroupUnbind(ImChannelContext imChannelContext, String group) throws ImException;
/**
* 绑定用户后回调该方法
- * @param channelContext
+ * @param imChannelContext
* @param userId
* @throws Exception
*/
- void onAfterUserBind(ChannelContext channelContext, String userId) throws Exception;
+ void onAfterUserBind(ImChannelContext imChannelContext, String userId) throws ImException;
/**
* 解绑用户后回调该方法
- * @param channelContext
+ * @param imChannelContext
* @param userId
* @throws Exception
*/
- void onAfterUserUnbind(ChannelContext channelContext, String userId) throws Exception;
+ void onAfterUserUnbind(ImChannelContext imChannelContext, String userId) throws Exception;
/**
* 更新用户终端协议类型及在线状态;
- * @param channelContext
+ * @param imChannelContext
* @param terminal(ws、tcp、http、android、ios等)
* @param status(online、offline)
*/
- void initUserTerminal(ChannelContext channelContext , String terminal , String status);
+ void initUserTerminal(ImChannelContext imChannelContext , String terminal , String status);
}
diff --git a/jim-common/src/main/java/org/jim/common/listener/ImGroupListener.java b/jim-common/src/main/java/org/jim/common/listener/ImGroupListener.java
new file mode 100644
index 0000000..a543fcb
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/listener/ImGroupListener.java
@@ -0,0 +1,32 @@
+package org.jim.common.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.exception.ImException;
+import org.tio.core.ChannelContext;
+
+/**
+ * @ClassName ImGroupListener
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/12 14:17
+ * @Version 1.0
+ **/
+public interface ImGroupListener {
+ /**
+ * 绑定群组后回调该方法
+ * @param imChannelContext
+ * @param group
+ * @throws ImException
+ * @author WChao
+ */
+ void onAfterBind(ImChannelContext imChannelContext, String group) throws ImException;
+
+ /**
+ * 解绑群组后回调该方法
+ * @param imChannelContext
+ * @param group
+ * @throws ImException
+ * @author WChao
+ */
+ void onAfterUnbind(ImChannelContext imChannelContext, String group) throws ImException;
+}
diff --git a/jim-common/src/main/java/org/jim/common/listener/ImGroupListenerAdapter.java b/jim-common/src/main/java/org/jim/common/listener/ImGroupListenerAdapter.java
new file mode 100644
index 0000000..c4bc42d
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/listener/ImGroupListenerAdapter.java
@@ -0,0 +1,34 @@
+package org.jim.common.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.tio.core.ChannelContext;
+import org.tio.core.intf.GroupListener;
+
+/**
+ * @ClassName ImGroupListenerAdapter
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/12 14:19
+ * @Version 1.0
+ **/
+public class ImGroupListenerAdapter implements GroupListener, ImConst {
+
+ private ImGroupListener imGroupListener;
+
+ public ImGroupListenerAdapter(ImGroupListener imGroupListener){
+ this.imGroupListener = imGroupListener;
+ }
+
+ @Override
+ public void onAfterBind(ChannelContext channelContext, String group) throws Exception {
+ ImChannelContext imChannelContext = (ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY);
+ imGroupListener.onAfterBind(imChannelContext, group);
+ }
+
+ @Override
+ public void onAfterUnbind(ChannelContext channelContext, String group) throws Exception {
+ ImChannelContext imChannelContext = (ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY);
+ imGroupListener.onAfterBind(imChannelContext, group);
+ }
+}
diff --git a/jim-common/src/main/java/org/jim/common/listener/ImListener.java b/jim-common/src/main/java/org/jim/common/listener/ImListener.java
new file mode 100644
index 0000000..2060e60
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/listener/ImListener.java
@@ -0,0 +1,75 @@
+package org.jim.common.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImPacket;
+import org.tio.core.ChannelContext;
+import org.tio.core.intf.Packet;
+
+/**
+ * @ClassName ImListener
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/4 11:09
+ * @Version 1.0
+ **/
+public interface ImListener {
+ /**
+ * 建链后触发本方法,注:建链不一定成功,需要关注参数isConnected
+ * @param imChannelContext
+ * @param isConnected 是否连接成功,true:表示连接成功,false:表示连接失败
+ * @param isReconnect 是否是重连, true: 表示这是重新连接,false: 表示这是第一次连接
+ * @throws Exception
+ * @author: WChao
+ */
+ void onAfterConnected(ImChannelContext imChannelContext, boolean isConnected, boolean isReconnect) throws Exception;
+
+ /**
+ * 原方法名:onAfterDecoded
+ * 解码成功后触发本方法
+ * @param imChannelContext
+ * @param packet
+ * @param packetSize
+ * @throws Exception
+ * @author: WChao
+ */
+ void onAfterDecoded(ImChannelContext imChannelContext, ImPacket packet, int packetSize) throws Exception;
+
+ /**
+ * 接收到TCP层传过来的数据后
+ * @param imChannelContext
+ * @param receivedBytes 本次接收了多少字节
+ * @throws Exception
+ */
+ void onAfterReceivedBytes(ImChannelContext imChannelContext, int receivedBytes) throws Exception;
+
+ /**
+ * 消息包发送之后触发本方法
+ * @param imChannelContext
+ * @param packet
+ * @param isSentSuccess true:发送成功,false:发送失败
+ * @throws Exception
+ * @author WChao
+ */
+ void onAfterSent(ImChannelContext imChannelContext, ImPacket packet, boolean isSentSuccess) throws Exception;
+
+ /**
+ * 处理一个消息包后
+ * @param imChannelContext
+ * @param packet
+ * @param cost 本次处理消息耗时,单位:毫秒
+ * @throws Exception
+ */
+ void onAfterHandled(ImChannelContext imChannelContext, ImPacket packet, long cost) throws Exception;
+
+ /**
+ * 连接关闭前触发本方法
+ * @param imChannelContext
+ * @param throwable the throwable 有可能为空
+ * @param remark the remark 有可能为空
+ * @param isRemove
+ * @author WChao
+ * @throws Exception
+ */
+ void onBeforeClose(ImChannelContext imChannelContext, Throwable throwable, String remark, boolean isRemove) throws Exception;
+
+}
diff --git a/jim-common/src/main/java/org/jim/common/listener/ImUserListener.java b/jim-common/src/main/java/org/jim/common/listener/ImUserListener.java
new file mode 100644
index 0000000..e7699f2
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/listener/ImUserListener.java
@@ -0,0 +1,31 @@
+package org.jim.common.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.exception.ImException;
+
+/**
+ * @ClassName ImUserListener
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/12 14:24
+ * @Version 1.0
+ **/
+public interface ImUserListener {
+ /**
+ * 绑定用户后回调该方法
+ * @param imChannelContext
+ * @param userId
+ * @throws Exception
+ * @author WChao
+ */
+ void onAfterBind(ImChannelContext imChannelContext, String userId) throws ImException;
+
+ /**
+ * 解绑用户后回调该方法
+ * @param imChannelContext
+ * @param userId
+ * @throws Exception
+ * @author WChao
+ */
+ void onAfterUnbind(ImChannelContext imChannelContext, String userId) throws ImException;
+}
diff --git a/jim-common/src/main/java/org/jim/common/message/AbstractMessageHelper.java b/jim-common/src/main/java/org/jim/common/message/AbstractMessageHelper.java
index ba0ca60..dac6022 100644
--- a/jim-common/src/main/java/org/jim/common/message/AbstractMessageHelper.java
+++ b/jim-common/src/main/java/org/jim/common/message/AbstractMessageHelper.java
@@ -4,7 +4,7 @@
package org.jim.common.message;
import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
+import org.jim.common.config.ImConfig;
/**
* @author HP
diff --git a/jim-common/src/main/java/org/jim/common/packets/JoinGroupNotifyRespBody.java b/jim-common/src/main/java/org/jim/common/packets/JoinGroupNotifyRespBody.java
index 5840410..55dd5a1 100644
--- a/jim-common/src/main/java/org/jim/common/packets/JoinGroupNotifyRespBody.java
+++ b/jim-common/src/main/java/org/jim/common/packets/JoinGroupNotifyRespBody.java
@@ -3,17 +3,23 @@
*/
package org.jim.common.packets;
+import org.jim.common.ImStatus;
+import org.jim.common.Status;
+
/**
* 版本: [1.0]
* 功能说明: 进入群组通知消息体
* 作者: WChao 创建时间: 2017年7月26日 下午5:14:04
*/
-public class JoinGroupNotifyRespBody extends Message{
+public class JoinGroupNotifyRespBody extends RespBody{
private static final long serialVersionUID = 3828976681110713803L;
private User user;
private String group;
-
+
+ public JoinGroupNotifyRespBody(Command command, Status status){
+ super(command,status);
+ }
public User getUser() {
return user;
}
diff --git a/jim-common/src/main/java/org/jim/common/packets/JoinGroupRespBody.java b/jim-common/src/main/java/org/jim/common/packets/JoinGroupRespBody.java
index 4ca9d0b..ddea079 100644
--- a/jim-common/src/main/java/org/jim/common/packets/JoinGroupRespBody.java
+++ b/jim-common/src/main/java/org/jim/common/packets/JoinGroupRespBody.java
@@ -3,6 +3,8 @@
*/
package org.jim.common.packets;
+import org.jim.common.Status;
+
/**
* 版本: [1.0]
* 功能说明: 加入群组响应
@@ -13,6 +15,10 @@ public class JoinGroupRespBody extends RespBody {
private static final long serialVersionUID = 6635620192752369689L;
public JoinGroupResult result;
public String group;
+
+ public JoinGroupRespBody(Command command , Status status){
+ super(command, status);
+ }
public JoinGroupResult getResult() {
return result;
}
diff --git a/jim-common/src/main/java/org/jim/common/packets/RespBody.java b/jim-common/src/main/java/org/jim/common/packets/RespBody.java
index 007a962..b710ac3 100644
--- a/jim-common/src/main/java/org/jim/common/packets/RespBody.java
+++ b/jim-common/src/main/java/org/jim/common/packets/RespBody.java
@@ -15,16 +15,23 @@ import org.jim.common.utils.JsonKit;
public class RespBody implements Serializable{
private static final long serialVersionUID = 1L;
+ /**
+ * 响应状态码;
+ */
+ private Integer code;
+ /**
+ * 响应状态信息提示;
+ */
+ private String msg;
+ /**
+ * 响应cmd命令码;
+ */
+ private Command command;
+ /**
+ * 响应数据;
+ */
+ private Object data;
- private Integer code;//响应状态码;
-
- private String msg;//响应状态信息提示;
-
- private Command command;//响应cmd命令码;
-
- private Object data;//响应数据;
-
- public RespBody(){}
public RespBody(Command command){
this.command = command;
}
diff --git a/jim-common/src/main/java/org/jim/common/packets/User.java b/jim-common/src/main/java/org/jim/common/packets/User.java
index 131a721..380ed60 100644
--- a/jim-common/src/main/java/org/jim/common/packets/User.java
+++ b/jim-common/src/main/java/org/jim/common/packets/User.java
@@ -11,7 +11,7 @@ import java.util.List;
/**
* 版本: [1.0]
* 功能说明:
- * 作者: WChao 创建时间: 2017年7月26日 下午3:13:47
+ * @author : WChao 创建时间: 2017年7月26日 下午3:13:47
*/
public class User implements Serializable{
diff --git a/jim-common/src/main/java/org/jim/common/protocol/AbProtocol.java b/jim-common/src/main/java/org/jim/common/protocol/AbProtocol.java
deleted file mode 100644
index 798ad32..0000000
--- a/jim-common/src/main/java/org/jim/common/protocol/AbProtocol.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- *
- */
-package org.jim.common.protocol;
-
-import java.nio.ByteBuffer;
-
-import org.tio.core.ChannelContext;
-
-/**
- * @author WChao
- * @date 2018-09-05 23:52:00
- */
-public abstract class AbProtocol implements IProtocol {
- /**
- * 协议包转化器;
- */
- private IConvertProtocolPacket converter;
-
- public AbProtocol(){
- this.converter = converter();
- }
-
- /**
- * 根据buffer判断是否属于指定协议
- * @param buffer
- * @param channelContext
- * @return
- * @throws Throwable
- */
- public abstract boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable;
-
- public boolean isProtocol(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
- ByteBuffer copyByteBuffer = null;
- if(buffer != null && channelContext.getAttribute() == null){
- copyByteBuffer = ByteBuffer.wrap(buffer.array());
- }
- return isProtocolByBuffer(copyByteBuffer, channelContext);
- }
- public IConvertProtocolPacket getConverter() {
- return converter;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/protocol/AbstractProtocol.java b/jim-common/src/main/java/org/jim/common/protocol/AbstractProtocol.java
new file mode 100644
index 0000000..58a41f8
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/protocol/AbstractProtocol.java
@@ -0,0 +1,90 @@
+/**
+ *
+ */
+package org.jim.common.protocol;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.ImPacket;
+import org.jim.common.ImSessionContext;
+import org.jim.common.exception.ImException;
+/**
+ * @author WChao
+ * @date 2018-09-05 23:52:00
+ */
+public abstract class AbstractProtocol implements IProtocol,ImConst {
+ /**
+ * 协议包转化器;
+ */
+ protected IProtocolConverter converter;
+
+ public AbstractProtocol(IProtocolConverter converter){
+ this.converter = converter;
+ }
+ /**
+ * 协议初始化
+ * @param imChannelContext
+ */
+ protected abstract void init(ImChannelContext imChannelContext);
+ /**
+ * 根据buffer判断是否属于指定协议
+ * @param buffer
+ * @param imChannelContext
+ * @return
+ * @throws ImException
+ */
+ protected abstract boolean validateProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException;
+
+ /**
+ * 根据SessionContext判断协议
+ * @param imSessionContext
+ * @return
+ * @throws ImException
+ */
+ protected abstract boolean validateProtocol(ImSessionContext imSessionContext) throws ImException;
+
+ /**
+ * 根据imPacket判断是否属于指定协议
+ * @param imPacket
+ * @return
+ * @throws ImException
+ */
+ protected abstract boolean validateProtocol(ImPacket imPacket) throws ImException;
+
+ @Override
+ public boolean isProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException {
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
+ if(Objects.isNull(imSessionContext) && Objects.isNull(buffer)){
+ return false;
+ }else if(Objects.isNull(imSessionContext) && Objects.nonNull(buffer)){
+ boolean isProtocol = validateProtocol(ByteBuffer.wrap(buffer.array()), imChannelContext);
+ if(isProtocol){
+ init(imChannelContext);
+ }
+ return isProtocol;
+ }else{
+ return validateProtocol(imSessionContext);
+ }
+ }
+
+ @Override
+ public boolean isProtocol(ImPacket imPacket, ImChannelContext imChannelContext) throws ImException {
+ ImSessionContext sessionContext = imChannelContext.getSessionContext();
+ if(Objects.isNull(imPacket)){
+ return false;
+ }
+ boolean isProtocol = validateProtocol(imPacket);
+ if(isProtocol && Objects.isNull(sessionContext)) {
+ init(imChannelContext);
+ }
+ return isProtocol;
+ }
+
+ public IProtocolConverter getConverter() {
+ return converter;
+ }
+
+}
diff --git a/jim-common/src/main/java/org/jim/common/protocol/IProtocol.java b/jim-common/src/main/java/org/jim/common/protocol/IProtocol.java
index 455cd35..0dc380f 100644
--- a/jim-common/src/main/java/org/jim/common/protocol/IProtocol.java
+++ b/jim-common/src/main/java/org/jim/common/protocol/IProtocol.java
@@ -3,8 +3,11 @@
*/
package org.jim.common.protocol;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.tio.core.ChannelContext;
+import org.jim.common.exception.ImException;
+
+import java.nio.ByteBuffer;
/**
* 判断协议接口
@@ -16,20 +19,23 @@ public interface IProtocol {
* 协议名称
* @return 如:http、ws、tcp等
*/
- public String name();
+ String name();
/**
- * 判断是否属于指定协议
+ * 根据buffer判断是否属于指定协议
+ * @param buffer
+ * @param imChannelContext
+ * @return
+ * @throws ImException
+ */
+ boolean isProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException;
+
+ /**
+ * 根据imPacket判断是否属于指定协议
* @param imPacket
- * @param channelContext
+ * @param imChannelContext
* @return
- * @throws Throwable
+ * @throws ImException
*/
- public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext)throws Throwable;
-
- /**
- * 获取该协议包转化器
- * @return
- */
- public IConvertProtocolPacket converter();
+ boolean isProtocol(ImPacket imPacket, ImChannelContext imChannelContext)throws ImException;
}
diff --git a/jim-common/src/main/java/org/jim/common/protocol/IConvertProtocolPacket.java b/jim-common/src/main/java/org/jim/common/protocol/IProtocolConverter.java
similarity index 51%
rename from jim-common/src/main/java/org/jim/common/protocol/IConvertProtocolPacket.java
rename to jim-common/src/main/java/org/jim/common/protocol/IProtocolConverter.java
index d480dbf..cba7be5 100644
--- a/jim-common/src/main/java/org/jim/common/protocol/IConvertProtocolPacket.java
+++ b/jim-common/src/main/java/org/jim/common/protocol/IProtocolConverter.java
@@ -3,30 +3,29 @@
*/
package org.jim.common.protocol;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.jim.common.packets.Command;
-import org.tio.core.ChannelContext;
-
/**
* 转换不同协议消息包;
* @author WChao
*
*/
-public interface IConvertProtocolPacket {
+public interface IProtocolConverter {
/**
* 转化请求包
* @param body
* @param command
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public ImPacket ReqPacket(byte[] body,Command command, ChannelContext channelContext);
+ ImPacket ReqPacket(byte[] body,Command command, ImChannelContext imChannelContext);
/**
* 转化响应包
* @param body
* @param command
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public ImPacket RespPacket(byte[] body,Command command, ChannelContext channelContext);
+ ImPacket RespPacket(byte[] body,Command command, ImChannelContext imChannelContext);
}
diff --git a/jim-common/src/main/java/org/jim/common/session/id/impl/UUIDSessionIdGenerator.java b/jim-common/src/main/java/org/jim/common/session/id/impl/UUIDSessionIdGenerator.java
index cd99a41..3e2c4cc 100644
--- a/jim-common/src/main/java/org/jim/common/session/id/impl/UUIDSessionIdGenerator.java
+++ b/jim-common/src/main/java/org/jim/common/session/id/impl/UUIDSessionIdGenerator.java
@@ -5,9 +5,10 @@ import org.slf4j.LoggerFactory;
import org.jim.common.http.HttpConfig;
import org.jim.common.session.id.ISessionIdGenerator;
-import cn.hutool.core.util.RandomUtil;
+import java.util.UUID;
+
/**
- * @author wchao
+ * @author WChao
* 2017年8月15日 上午10:53:39
*/
public class UUIDSessionIdGenerator implements ISessionIdGenerator {
@@ -39,6 +40,6 @@ public class UUIDSessionIdGenerator implements ISessionIdGenerator {
*/
@Override
public String sessionId(HttpConfig httpConfig) {
- return RandomUtil.randomUUID().replace("-", "");
+ return UUID.randomUUID().toString().replace("-", "");
}
}
diff --git a/jim-common/src/main/java/org/jim/common/tcp/TcpConvertPacket.java b/jim-common/src/main/java/org/jim/common/tcp/TcpConvertPacket.java
index b81761d..b293347 100644
--- a/jim-common/src/main/java/org/jim/common/tcp/TcpConvertPacket.java
+++ b/jim-common/src/main/java/org/jim/common/tcp/TcpConvertPacket.java
@@ -3,27 +3,28 @@
*/
package org.jim.common.tcp;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
+import org.jim.common.ImSessionContext;
import org.jim.common.packets.Command;
-import org.jim.common.protocol.IConvertProtocolPacket;
-import org.tio.core.ChannelContext;
+import org.jim.common.protocol.IProtocolConverter;
/**
* TCP协议消息转化包
* @author WChao
*
*/
-public class TcpConvertPacket implements IConvertProtocolPacket {
+public class TcpConvertPacket implements IProtocolConverter {
/**
* 转TCP协议响应包;
*/
@Override
- public ImPacket RespPacket(byte[] body, Command command,ChannelContext channelContext) {
- Object sessionContext = channelContext.getAttribute();
- if(sessionContext instanceof TcpSessionContext){//转TCP协议响应包;
+ public ImPacket RespPacket(byte[] body, Command command, ImChannelContext imChannelContext) {
+ ImSessionContext sessionContext = imChannelContext.getSessionContext();
+ if(sessionContext instanceof TcpSessionContext){
TcpPacket tcpPacket = new TcpPacket(command,body);
- TcpServerEncoder.encode(tcpPacket, channelContext.getGroupContext(), channelContext);
+ TcpServerEncoder.encode(tcpPacket, imChannelContext.getImConfig(), imChannelContext);
tcpPacket.setCommand(command);
return tcpPacket;
}
@@ -33,11 +34,11 @@ public class TcpConvertPacket implements IConvertProtocolPacket {
* 转TCP协议请求包;
*/
@Override
- public ImPacket ReqPacket(byte[] body, Command command,ChannelContext channelContext) {
- Object sessionContext = channelContext.getAttribute();
- if(sessionContext instanceof TcpSessionContext){//转TCP协议请求包;
+ public ImPacket ReqPacket(byte[] body, Command command, ImChannelContext channelContext) {
+ Object sessionContext = channelContext.getSessionContext();
+ if(sessionContext instanceof TcpSessionContext){
TcpPacket tcpPacket = new TcpPacket(command,body);
- TcpServerEncoder.encode(tcpPacket, channelContext.getGroupContext(), channelContext);
+ TcpServerEncoder.encode(tcpPacket, channelContext.getImConfig(), channelContext);
tcpPacket.setCommand(command);
return tcpPacket;
}
diff --git a/jim-common/src/main/java/org/jim/common/tcp/TcpProtocol.java b/jim-common/src/main/java/org/jim/common/tcp/TcpProtocol.java
index 576b17b..54c8712 100644
--- a/jim-common/src/main/java/org/jim/common/tcp/TcpProtocol.java
+++ b/jim-common/src/main/java/org/jim/common/tcp/TcpProtocol.java
@@ -5,20 +5,24 @@ package org.jim.common.tcp;
import java.nio.ByteBuffer;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.jim.common.ImSessionContext;
-import org.jim.common.Protocol;
-import org.jim.common.protocol.AbProtocol;
-import org.jim.common.protocol.IConvertProtocolPacket;
+import org.jim.common.exception.ImException;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.protocol.IProtocolConverter;
import org.jim.common.utils.ImUtils;
-import org.tio.core.ChannelContext;
/**
* Tcp协议判断器
* @author WChao
*
*/
-public class TcpProtocol extends AbProtocol {
+public class TcpProtocol extends AbstractProtocol {
+
+ public TcpProtocol(IProtocolConverter converter){
+ super(converter);
+ }
@Override
public String name() {
@@ -26,39 +30,31 @@ public class TcpProtocol extends AbProtocol {
}
@Override
- public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- if(imSessionContext != null && imSessionContext instanceof TcpSessionContext) {
+ protected void init(ImChannelContext imChannelContext) {
+ imChannelContext.setSessionContext(new TcpSessionContext(imChannelContext));
+ ImUtils.setClient(imChannelContext);
+ }
+
+ @Override
+ public boolean validateProtocol(ImSessionContext imSessionContext) throws ImException {
+ if(imSessionContext instanceof TcpSessionContext){
return true;
}
- if(buffer != null){
- //获取第一个字节协议版本号;
- byte version = buffer.get();
- //TCP协议;
- if(version == Protocol.VERSION){
- channelContext.setAttribute(new TcpSessionContext());
- ImUtils.setClient(channelContext);
- return true;
- }
- }
return false;
}
@Override
- public IConvertProtocolPacket converter() {
- return new TcpConvertPacket();
- }
-
- @Override
- public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
- if(imPacket == null) {
- return false;
+ public boolean validateProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException {
+ //获取第一个字节协议版本号,TCP协议;
+ if(buffer.get() == Protocol.VERSION){
+ return true;
}
+ return false;
+ }
+
+ @Override
+ public boolean validateProtocol(ImPacket imPacket) throws ImException {
if(imPacket instanceof TcpPacket){
- Object sessionContext = channelContext.getAttribute();
- if(sessionContext == null){
- channelContext.setAttribute(new TcpSessionContext());
- }
return true;
}
return false;
diff --git a/jim-common/src/main/java/org/jim/common/tcp/TcpServerDecoder.java b/jim-common/src/main/java/org/jim/common/tcp/TcpServerDecoder.java
index 5344445..3a088d0 100644
--- a/jim-common/src/main/java/org/jim/common/tcp/TcpServerDecoder.java
+++ b/jim-common/src/main/java/org/jim/common/tcp/TcpServerDecoder.java
@@ -6,11 +6,11 @@ package org.jim.common.tcp;
import java.nio.ByteBuffer;
import org.apache.log4j.Logger;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
-import org.jim.common.Protocol;
-import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
+import org.jim.common.exception.ImDecodeException;
import org.jim.common.packets.Command;
/**
@@ -18,11 +18,11 @@ import org.jim.common.packets.Command;
* 功能说明:
* @author : WChao 创建时间: 2017年8月21日 下午3:08:04
*/
-public class TcpServerDecoder {
+public class TcpServerDecoder implements ImConst {
private static Logger logger = Logger.getLogger(TcpServerDecoder.class);
- public static TcpPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException{
+ public static TcpPacket decode(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImDecodeException {
//校验协议头
if(!isHeaderLength(buffer)) {
return null;
@@ -30,7 +30,7 @@ public class TcpServerDecoder {
//获取第一个字节协议版本号;
byte version = buffer.get();
if(version != Protocol.VERSION){
- throw new AioDecodeException(ImStatus.C10013.getText());
+ throw new ImDecodeException(ImStatus.C10013.getText());
}
//标志位
byte maskByte = buffer.get();
@@ -42,13 +42,13 @@ public class TcpServerDecoder {
//cmd命令码
byte cmdByte = buffer.get();
if(Command.forNumber(cmdByte) == null){
- throw new AioDecodeException(ImStatus.C10014.getText());
+ throw new ImDecodeException(ImStatus.C10014.getText());
}
int bodyLen = buffer.getInt();
- //数据不正确,则抛出AioDecodeException异常
+ //数据不正确,则抛出ImDecodeException异常
if (bodyLen < 0)
{
- throw new AioDecodeException("bodyLength [" + bodyLen + "] is not right, remote:" + channelContext.getClientNode());
+ throw new ImDecodeException("bodyLength [" + bodyLen + "] is not right, remote:" + imChannelContext.getClientNode());
}
int readableLength = buffer.limit() - buffer.position();
int validateBodyLen = readableLength - bodyLen;
@@ -72,7 +72,7 @@ public class TcpServerDecoder {
if(synSeq > 0){
tcpPacket.setSynSeq(synSeq);
try {
- channelContext.getGroupContext().getAioHandler().handler(tcpPacket, channelContext);
+ //channelContext.getGroupContext().getAioHandler().handler(tcpPacket, channelContext);
} catch (Exception e) {
logger.error("同步发送解码调用handler异常!"+e);
}
@@ -83,9 +83,9 @@ public class TcpServerDecoder {
* 判断是否符合协议头长度
* @param buffer
* @return
- * @throws AioDecodeException
+ * @throws ImDecodeException
*/
- private static boolean isHeaderLength(ByteBuffer buffer) throws AioDecodeException{
+ private static boolean isHeaderLength(ByteBuffer buffer) throws ImDecodeException{
int readableLength = buffer.limit() - buffer.position();
if(readableLength == 0) {
return false;
diff --git a/jim-common/src/main/java/org/jim/common/tcp/TcpServerEncoder.java b/jim-common/src/main/java/org/jim/common/tcp/TcpServerEncoder.java
index e898cfa..e6a5f01 100644
--- a/jim-common/src/main/java/org/jim/common/tcp/TcpServerEncoder.java
+++ b/jim-common/src/main/java/org/jim/common/tcp/TcpServerEncoder.java
@@ -6,18 +6,18 @@ package org.jim.common.tcp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
import org.jim.common.ImPacket;
-import org.jim.common.Protocol;
-import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
+import org.jim.common.config.ImConfig;
/**
* 版本: [1.0]
* 功能说明:
* @author : WChao 创建时间: 2017年8月21日 下午4:00:31
*/
-public class TcpServerEncoder {
+public class TcpServerEncoder implements ImConst {
- public static ByteBuffer encode(TcpPacket tcpPacket, GroupContext groupContext, ChannelContext channelContext){
+ public static ByteBuffer encode(TcpPacket tcpPacket, ImConfig imConfig, ImChannelContext imChannelContext){
int bodyLen = 0;
byte[] body = tcpPacket.getBody();
if (body != null)
@@ -53,7 +53,7 @@ public class TcpServerEncoder {
allLen += 1+4+bodyLen;
ByteBuffer buffer = ByteBuffer.allocate(allLen);
//设置字节序
- ByteOrder byteOrder = groupContext == null ? ByteOrder.BIG_ENDIAN : groupContext.getByteOrder();
+ ByteOrder byteOrder = imConfig == null ? ByteOrder.BIG_ENDIAN : imConfig.getTioConfig().getByteOrder();
buffer.order(byteOrder);
buffer.put(tcpPacket.getVersion());
buffer.put(tcpPacket.getMask());
diff --git a/jim-common/src/main/java/org/jim/common/tcp/TcpSessionContext.java b/jim-common/src/main/java/org/jim/common/tcp/TcpSessionContext.java
index c23f599..324322c 100644
--- a/jim-common/src/main/java/org/jim/common/tcp/TcpSessionContext.java
+++ b/jim-common/src/main/java/org/jim/common/tcp/TcpSessionContext.java
@@ -3,12 +3,17 @@
*/
package org.jim.common.tcp;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImSessionContext;
/**
* 版本: [1.0]
* 功能说明:
- * 作者: WChao 创建时间: 2017年9月6日 下午5:03:15
+ * @author : WChao 创建时间: 2017年9月6日 下午5:03:15
*/
public class TcpSessionContext extends ImSessionContext {
+ public TcpSessionContext(ImChannelContext imChannelContext){
+ super(imChannelContext);
+ }
+
}
diff --git a/jim-common/src/main/java/org/jim/common/utils/ChatKit.java b/jim-common/src/main/java/org/jim/common/utils/ChatKit.java
index e04091c..d32647c 100644
--- a/jim-common/src/main/java/org/jim/common/utils/ChatKit.java
+++ b/jim-common/src/main/java/org/jim/common/utils/ChatKit.java
@@ -5,12 +5,9 @@ package org.jim.common.utils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
-import org.jim.common.ImConst;
-import org.jim.common.ImAio;
-import org.jim.common.ImPacket;
-import org.jim.common.ImSessionContext;
-import org.jim.common.ImStatus;
-import org.jim.common.config.Config;
+import org.jim.common.*;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpConst;
import org.jim.common.packets.ChatBody;
import org.jim.common.packets.Command;
@@ -18,7 +15,7 @@ import org.jim.common.packets.RespBody;
import org.jim.common.packets.User;
import org.jim.common.session.id.impl.UUIDSessionIdGenerator;
import org.tio.core.ChannelContext;
-import org.tio.utils.lock.SetWithLock;
+
/**
* IM聊天命令工具类
* @date 2018-09-05 23:29:30
@@ -32,19 +29,19 @@ public class ChatKit {
/**
* 转换为聊天消息结构;
* @param body
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public static ChatBody toChatBody(byte[] body,ChannelContext channelContext){
+ public static ChatBody toChatBody(byte[] body,ImChannelContext imChannelContext){
ChatBody chatReqBody = parseChatBody(body);
if(chatReqBody != null){
if(StringUtils.isEmpty(chatReqBody.getFrom())){
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
User user = imSessionContext.getClient().getUser();
if(user != null){
chatReqBody.setFrom(user.getNick());
}else{
- chatReqBody.setFrom(channelContext.getId());
+ chatReqBody.setFrom(imChannelContext.getId());
}
}
}
@@ -62,7 +59,7 @@ public class ChatKit {
}
ChatBody chatReqBody = null;
try{
- String text = new String(body,HttpConst.CHARSET_NAME);
+ String text = new String(body,ImConst.CHARSET);
chatReqBody = JsonKit.toBean(text,ChatBody.class);
if(chatReqBody != null){
if(chatReqBody.getCreateTime() == null) {
@@ -89,67 +86,28 @@ public class ChatKit {
return null;
}
try {
- return parseChatBody(bodyStr.getBytes(HttpConst.CHARSET_NAME));
+ return parseChatBody(bodyStr.getBytes(ImConst.CHARSET));
} catch (Exception e) {
log.error(e);
}
return null;
}
- /**
- * 聊天数据格式不正确响应包
- * @param channelContext
- * @return imPacket
- * @throws Exception
- */
- public static ImPacket dataInCorrectRespPacket(ChannelContext channelContext) throws Exception{
- RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10002);
- ImPacket respPacket = ImKit.ConvertRespPacket(chatDataInCorrectRespPacket, channelContext);
- respPacket.setStatus(ImStatus.C10002);
- return respPacket;
- }
-
- /**
- * 聊天发送成功响应包
- * @param channelContext
- * @return imPacket
- * @throws Exception
- */
- public static ImPacket sendSuccessRespPacket(ChannelContext channelContext) throws Exception{
- RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10000);
- ImPacket respPacket = ImKit.ConvertRespPacket(chatDataInCorrectRespPacket, channelContext);
- respPacket.setStatus(ImStatus.C10000);
- return respPacket;
- }
-
- /**
- * 聊天用户不在线响应包
- * @param channelContext
- * @return
- * @throws Exception
- */
- public static ImPacket offlineRespPacket(ChannelContext channelContext) throws Exception{
- RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10001);
- ImPacket respPacket = ImKit.ConvertRespPacket(chatDataInCorrectRespPacket, channelContext);
- respPacket.setStatus(ImStatus.C10001);
- return respPacket;
- }
-
/**
* 判断用户是否在线
* @param userId
* @param imConfig
* @return
*/
- public static boolean isOnline(String userId ,Config imConfig){
- boolean isStore = ImConst.ON.equals(imConfig.getIsStore());
+ public static boolean isOnline(String userId , ImConfig imConfig){
+ /* boolean isStore = ImConst.ON.equals(imConfig.getIsStore());
if(isStore){
return imConfig.getMessageHelper().isOnline(userId);
}
- SetWithLock toChannelContexts = ImAio.getChannelContextsByUserId(userId);
+ SetWithLock toChannelContexts = Jim.getChannelContextsByUserId(userId);
if(toChannelContexts != null && toChannelContexts.size() > 0){
return true;
- }
+ }*/
return false;
}
diff --git a/jim-common/src/main/java/org/jim/common/utils/ImKit.java b/jim-common/src/main/java/org/jim/common/utils/ImKit.java
index cef10e6..3fd648a 100644
--- a/jim-common/src/main/java/org/jim/common/utils/ImKit.java
+++ b/jim-common/src/main/java/org/jim/common/utils/ImKit.java
@@ -4,23 +4,23 @@
package org.jim.common.utils;
import cn.hutool.core.bean.BeanUtil;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
-import org.jim.common.http.HttpConst;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpProtocol;
import org.jim.common.packets.Command;
import org.jim.common.packets.Group;
import org.jim.common.packets.RespBody;
import org.jim.common.packets.User;
-import org.jim.common.protocol.AbProtocol;
-import org.jim.common.protocol.IConvertProtocolPacket;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.protocol.IProtocolConverter;
import org.jim.common.protocol.IProtocol;
import org.jim.common.tcp.TcpProtocol;
import org.jim.common.ws.WsProtocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.ChannelContext;
import java.nio.ByteBuffer;
import java.util.ArrayList;
@@ -36,108 +36,7 @@ import java.util.Map.Entry;
public class ImKit {
private static Logger logger = LoggerFactory.getLogger(ImKit.class);
- private static Map protocols = new HashMap();
-
- static{
- WsProtocol wsProtocol = new WsProtocol();
- TcpProtocol tcpProtocol = new TcpProtocol();
- HttpProtocol httpProtocol = new HttpProtocol();
- protocols.put(wsProtocol.name(),wsProtocol);
- protocols.put(tcpProtocol.name(),tcpProtocol);
- protocols.put(httpProtocol.name(),httpProtocol);
- }
- /**
- * 功能描述:[转换不同协议响应包]
- * @author:WChao 创建时间: 2017年9月21日 下午3:21:54
- * @param respBody
- * @param channelContext
- * @return
- *
- */
- public static ImPacket ConvertRespPacket(RespBody respBody, ChannelContext channelContext){
- ImPacket respPacket = null;
- if(respBody == null) {
- return respPacket;
- }
- byte[] body;
- try {
- body = respBody.toString().getBytes(HttpConst.CHARSET_NAME);
- respPacket = ConvertRespPacket(body,respBody.getCommand(), channelContext);
- } catch (Exception e) {
- logger.error(e.getMessage());
- }
- return respPacket;
- }
-
- /**
- * 功能描述:[转换不同协议响应包]
- * @author:WChao 创建时间: 2017年9月21日 下午3:21:54
- * @param body
- * @param channelContext
- * @return
- *
- */
- public static ImPacket ConvertRespPacket(byte[] body,Command command, ChannelContext channelContext){
- ImPacket respPacket = null;
- IConvertProtocolPacket converter = (IConvertProtocolPacket)channelContext.getAttribute(ImConst.CONVERTER);
- if(converter != null){
- return converter.RespPacket(body, command, channelContext);
- }
- for(Entry entry : protocols.entrySet()){
- AbProtocol protocol = entry.getValue();
- IConvertProtocolPacket converterObj = protocol.getConverter();
- respPacket = converterObj.RespPacket(body, command, channelContext);
- if(respPacket != null){
- channelContext.setAttribute(ImConst.CONVERTER, converterObj);
- return respPacket;
- }
- }
- return respPacket;
- }
-
- public static ImPacket ConvertRespPacket(ImPacket imPacket,Command command, ChannelContext channelContext){
- ImPacket respPacket = ConvertRespPacket(imPacket.getBody(), command, channelContext);
- if(respPacket == null){
- for(Entry entry : protocols.entrySet()){
- AbProtocol protocol = entry.getValue();
- try{
- boolean isProtocol = protocol.isProtocol(imPacket,channelContext);
- if(isProtocol){
- IConvertProtocolPacket converterObj = protocol.getConverter();
- respPacket = converterObj.RespPacket(imPacket.getBody(), command, channelContext);
- if(respPacket != null){
- channelContext.setAttribute(ImConst.CONVERTER, converterObj);
- return respPacket;
- }
- }
- }catch(Throwable e){
- logger.error(e.toString());
- }
- }
- }
- return respPacket;
- }
-
- /**
- * 获取所属终端协议;
- * @param byteBuffer
- * @param channelContext
- */
- public static IProtocol protocol(ByteBuffer byteBuffer , ChannelContext channelContext){
- for(Entry entry : protocols.entrySet()){
- AbProtocol protocol = entry.getValue();
- try {
- boolean isProtocol = protocol.isProtocol(byteBuffer, channelContext);
- if(isProtocol){
- return protocol;
- }
- } catch (Throwable e) {
- logger.error(e.toString(),e);
- }
- }
- return null;
- }
/**
* 格式化状态码消息响应体;
@@ -145,17 +44,9 @@ public class ImKit {
* @return
*/
public static byte[] toImStatusBody(ImStatus status){
- return JsonKit.toJsonBytes(new RespBody().setCode(status.getCode()).setMsg(status.getDescription()+" "+status.getText()));
+ return JsonKit.toJsonBytes(new RespBody(status).setMsg(status.getDescription()+" "+status.getText()));
}
- /**
- * 获取所有协议判断器,目前内置(HttpProtocol、WebSocketProtocol、HttpProtocol)
- * @return
- */
- public static Map getProtocols() {
- return protocols;
- }
-
/**
* 复制用户信息不包括friends、groups下的users信息;
* @param source
diff --git a/jim-common/src/main/java/org/jim/common/utils/ImUtils.java b/jim-common/src/main/java/org/jim/common/utils/ImUtils.java
index 0b72035..e184163 100644
--- a/jim-common/src/main/java/org/jim/common/utils/ImUtils.java
+++ b/jim-common/src/main/java/org/jim/common/utils/ImUtils.java
@@ -3,6 +3,7 @@ package org.jim.common.utils;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImSessionContext;
import org.tio.core.ChannelContext;
import org.jim.common.packets.Client;
@@ -16,10 +17,10 @@ public class ImUtils {
* 设置Client对象到ImSessionContext中
* @param channelContext
* @return
- * @author: wchao
+ * @author: WChao
*/
- public static Client setClient(ChannelContext channelContext) {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ public static Client setClient(ImChannelContext channelContext) {
+ ImSessionContext imSessionContext = channelContext.getSessionContext();
Client client = imSessionContext.getClient();
if (client == null) {
client = new Client();
@@ -28,7 +29,6 @@ public class ImUtils {
client.setPort(channelContext.getClientNode().getPort());
imSessionContext.setClient(client);
}
-
return client;
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/IWsMsgHandler.java b/jim-common/src/main/java/org/jim/common/ws/IWsMsgHandler.java
index 20b3b4e..68f3aa0 100644
--- a/jim-common/src/main/java/org/jim/common/ws/IWsMsgHandler.java
+++ b/jim-common/src/main/java/org/jim/common/ws/IWsMsgHandler.java
@@ -1,5 +1,6 @@
package org.jim.common.ws;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.tio.core.ChannelContext;
import org.jim.common.ws.WsRequestPacket;
@@ -13,43 +14,43 @@ public interface IWsMsgHandler
/**
*
* @param packet
- * @param channelContext
+ * @param imChannelContext
* @return
*
* @author: WChao
* 2016年11月18日 下午1:08:45
*
*/
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception;
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws Exception;
/**
- * @param websocketPacket
+ * @param wsPacket
* @param text
- * @param channelContext
+ * @param imChannelContext
* @return 可以是WsResponsePacket、byte[]、ByteBuffer、String或null,如果是null,框架不会回消息
* @throws Exception
* @author: WChao
*/
- Object onText(WsRequestPacket wsPacket, String text, ChannelContext channelContext) throws Exception;
+ Object onText(WsRequestPacket wsPacket, String text, ImChannelContext imChannelContext) throws Exception;
/**
*
- * @param websocketPacket
+ * @param webSocketPacket
* @param bytes
* @param channelContext
* @return 可以是WsResponsePacket、byte[]、ByteBuffer、String或null,如果是null,框架不会回消息
* @throws Exception
* @author: WChao
*/
- Object onClose(WsRequestPacket websocketPacket, byte[] bytes, ChannelContext channelContext) throws Exception;
+ Object onClose(WsRequestPacket webSocketPacket, byte[] bytes, ImChannelContext channelContext) throws Exception;
/**
*
- * @param websocketPacket
+ * @param webSocketPacket
* @param bytes
- * @param channelContext
+ * @param imChannelContext
* @return 可以是WsResponsePacket、byte[]、ByteBuffer、String或null,如果是null,框架不会回消息
* @throws Exception
* @author: WChao
*/
- Object onBytes(WsRequestPacket websocketPacket, byte[] bytes, ChannelContext channelContext) throws Exception;
+ Object onBytes(WsRequestPacket webSocketPacket, byte[] bytes, ImChannelContext imChannelContext) throws Exception;
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsConfig.java b/jim-common/src/main/java/org/jim/common/ws/WsConfig.java
new file mode 100644
index 0000000..bd79761
--- /dev/null
+++ b/jim-common/src/main/java/org/jim/common/ws/WsConfig.java
@@ -0,0 +1,71 @@
+package org.jim.common.ws;
+
+import org.jim.common.ImConst;
+import org.jim.common.config.ImConfig;
+import org.jim.common.http.HttpConst;
+
+/**
+ *
+ * 版本: [1.0]
+ * 功能说明:
+ * @author : WChao 创建时间: 2017年9月6日 上午11:11:26
+ */
+public class WsConfig implements ImConst {
+
+ private String charset = Http.CHARSET_NAME;
+
+ private IWsMsgHandler wsMsgHandler;
+
+ public WsConfig(){};
+
+ public WsConfig(IWsMsgHandler wsMsgHandler){
+ this.wsMsgHandler = wsMsgHandler;
+ }
+
+ public static WsConfig.Builder newBuilder(){
+ return new WsConfig.Builder();
+ }
+
+ /**
+ * @return the charset
+ */
+ public String getCharset() {
+ return charset;
+ }
+
+ /**
+ * @param charset the charset to set
+ */
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
+ public IWsMsgHandler getWsMsgHandler() {
+ return wsMsgHandler;
+ }
+ public void setWsMsgHandler(IWsMsgHandler wsMsgHandler) {
+ this.wsMsgHandler = wsMsgHandler;
+ }
+
+ public static class Builder{
+
+ private IWsMsgHandler wsMsgHandler;
+
+ private String charset;
+
+ public Builder wsMsgHandler(IWsMsgHandler wsMsgHandler){
+ this.wsMsgHandler = wsMsgHandler;
+ return this;
+ }
+
+ public Builder charset(String charset){
+ this.charset = charset;
+ return this;
+ }
+
+ public WsConfig build(){
+ WsConfig wsConfig = new WsConfig(wsMsgHandler);
+ wsConfig.setCharset(charset);
+ return wsConfig;
+ }
+ }
+}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsConvertPacket.java b/jim-common/src/main/java/org/jim/common/ws/WsConvertPacket.java
index 4e1172f..ed463c7 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsConvertPacket.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsConvertPacket.java
@@ -3,24 +3,24 @@
*/
package org.jim.common.ws;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
+import org.jim.common.ImSessionContext;
import org.jim.common.packets.Command;
-import org.jim.common.protocol.IConvertProtocolPacket;
-import org.tio.core.ChannelContext;
-
+import org.jim.common.protocol.IProtocolConverter;
/**
* Ws协议消息转化包
* @author WChao
*
*/
-public class WsConvertPacket implements IConvertProtocolPacket {
+public class WsConvertPacket implements IProtocolConverter {
/**
* WebSocket响应包;
*/
@Override
- public ImPacket RespPacket(byte[] body, Command command,ChannelContext channelContext) {
- Object sessionContext = channelContext.getAttribute();
+ public ImPacket RespPacket(byte[] body, Command command, ImChannelContext channelContext) {
+ ImSessionContext sessionContext = channelContext.getSessionContext();
//转ws协议响应包;
if(sessionContext instanceof WsSessionContext){
WsResponsePacket wsResponsePacket = new WsResponsePacket();
@@ -33,7 +33,7 @@ public class WsConvertPacket implements IConvertProtocolPacket {
}
@Override
- public ImPacket ReqPacket(byte[] body, Command command,ChannelContext channelContext) {
+ public ImPacket ReqPacket(byte[] body, Command command, ImChannelContext channelContext) {
return null;
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsProtocol.java b/jim-common/src/main/java/org/jim/common/ws/WsProtocol.java
index ab6d53a..03b386b 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsProtocol.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsProtocol.java
@@ -5,65 +5,62 @@ package org.jim.common.ws;
import java.nio.ByteBuffer;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.jim.common.ImSessionContext;
-import org.jim.common.Protocol;
-import org.jim.common.http.HttpConst;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpRequestDecoder;
-import org.jim.common.protocol.AbProtocol;
-import org.jim.common.protocol.IConvertProtocolPacket;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.protocol.IProtocolConverter;
import org.jim.common.utils.ImUtils;
-import org.tio.core.ChannelContext;
-
/**
* WebSocket协议判断器
* @author WChao
*
*/
-public class WsProtocol extends AbProtocol {
+public class WsProtocol extends AbstractProtocol {
@Override
public String name() {
- return Protocol.WEBSOCKET;
+ return Protocol.WEB_SOCKET;
+ }
+
+ public WsProtocol(IProtocolConverter converter){
+ super(converter);
}
@Override
- public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- if(imSessionContext != null && imSessionContext instanceof WsSessionContext) {
+ protected void init(ImChannelContext imChannelContext) {
+ imChannelContext.setSessionContext(new WsSessionContext(imChannelContext));
+ ImUtils.setClient(imChannelContext);
+ }
+
+ @Override
+ protected boolean validateProtocol(ImSessionContext imSessionContext) throws ImException {
+ if(imSessionContext instanceof WsSessionContext) {
return true;
}
- //第一次连接;
- if(buffer != null){
- HttpRequest request = HttpRequestDecoder.decode(buffer, channelContext,false);
- if(request.getHeaders().get(HttpConst.RequestHeaderKey.Sec_WebSocket_Key) != null)
- {
- channelContext.setAttribute(new WsSessionContext());
- ImUtils.setClient(channelContext);
- return true;
- }
- }
return false;
}
@Override
- public IConvertProtocolPacket converter() {
- return new WsConvertPacket();
- }
-
- @Override
- public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
- if(imPacket == null) {
- return false;
- }
- if(imPacket instanceof WsPacket){
- Object sessionContext = channelContext.getAttribute();
- if(sessionContext == null){
- channelContext.setAttribute(new WsSessionContext());
- }
+ protected boolean validateProtocol(ByteBuffer buffer, ImChannelContext imChannelContext) throws ImException {
+ //第一次连接;
+ HttpRequest request = HttpRequestDecoder.decode(buffer, imChannelContext,false);
+ if(request.getHeaders().get(Http.RequestHeaderKey.Sec_WebSocket_Key) != null)
+ {
return true;
}
return false;
}
+
+ @Override
+ public boolean validateProtocol(ImPacket imPacket) throws ImException {
+ if(imPacket instanceof WsPacket){
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsServerConfig.java b/jim-common/src/main/java/org/jim/common/ws/WsServerConfig.java
deleted file mode 100644
index dce5b39..0000000
--- a/jim-common/src/main/java/org/jim/common/ws/WsServerConfig.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.jim.common.ws;
-
-import org.jim.common.config.Config;
-import org.jim.common.http.HttpConst;
-
-/**
- *
- * 版本: [1.0]
- * 功能说明:
- * @author : WChao 创建时间: 2017年9月6日 上午11:11:26
- */
-public class WsServerConfig extends Config{
-
- private String charset = HttpConst.CHARSET_NAME;
-
- private IWsMsgHandler wsMsgHandler;
-
- public WsServerConfig(){};
-
- public WsServerConfig(Integer bindPort) {
- this.bindPort = bindPort;
- }
- /**
- * @return the charset
- */
- public String getCharset() {
- return charset;
- }
-
- /**
- * @param charset the charset to set
- */
- public void setCharset(String charset) {
- this.charset = charset;
- }
- public IWsMsgHandler getWsMsgHandler() {
- return wsMsgHandler;
- }
- public void setWsMsgHandler(IWsMsgHandler wsMsgHandler) {
- this.wsMsgHandler = wsMsgHandler;
- }
-}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsServerDecoder.java b/jim-common/src/main/java/org/jim/common/ws/WsServerDecoder.java
index 46d31d4..f2cd6b4 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsServerDecoder.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsServerDecoder.java
@@ -8,12 +8,12 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.exception.ImDecodeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
import org.tio.core.utils.ByteBufferUtils;
-import org.jim.common.http.HttpConst;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpResponse;
import org.jim.common.http.HttpResponseStatus;
@@ -24,15 +24,15 @@ import org.jim.common.utils.SHA1Util;
* @author wchao
* 2017年7月30日 上午10:10:50
*/
-public class WsServerDecoder {
- public static enum Step {
+public class WsServerDecoder implements ImConst{
+ public enum Step {
header, remain_header, data,
}
private static Logger log = LoggerFactory.getLogger(WsServerDecoder.class);
- public static WsRequestPacket decode(ByteBuffer buf, ChannelContext channelContext) throws AioDecodeException {
- WsSessionContext imSessionContext = (WsSessionContext) channelContext.getAttribute();
+ public static WsRequestPacket decode(ByteBuffer buf, ImChannelContext imChannelContext) throws ImDecodeException {
+ WsSessionContext imSessionContext = (WsSessionContext) imChannelContext.getSessionContext();
List lastParts = imSessionContext.getLastParts();
//第一阶段解析
@@ -70,7 +70,7 @@ public class WsServerDecoder {
// Client data must be masked
if (!hasMask) { //第9为为mask,必须为1
- //throw new AioDecodeException("websocket client data must be masked");
+ //throw new ImDecodeException("websocket client data must be masked");
} else {
headLength += 4;
}
@@ -83,7 +83,7 @@ public class WsServerDecoder {
return null;
}
payloadLength = ByteBufferUtils.readUB2WithBigEdian(buf);
- log.info("{} payloadLengthFlag: 126,payloadLength {}", channelContext, payloadLength);
+ log.info("{} payloadLengthFlag: 126,payloadLength {}", imChannelContext, payloadLength);
} else if (payloadLength == 127) { //127读8个字节,后8个字节为payloadLength
headLength += 8;
@@ -92,11 +92,11 @@ public class WsServerDecoder {
}
payloadLength = (int) buf.getLong();
- log.info("{} payloadLengthFlag: 127,payloadLength {}", channelContext, payloadLength);
+ log.info("{} payloadLengthFlag: 127,payloadLength {}", imChannelContext, payloadLength);
}
if (payloadLength < 0 || payloadLength > WsPacket.MAX_BODY_LENGTH) {
- throw new AioDecodeException("body length(" + payloadLength + ") is not right");
+ throw new ImDecodeException("body length(" + payloadLength + ") is not right");
}
if (readableLength < headLength + payloadLength) {
@@ -173,14 +173,14 @@ public class WsServerDecoder {
* 本方法改编自baseio: https://git.oschina.net/generallycloud/baseio
* 感谢开源作者的付出
* @param request
- * @param channelContext
+ * @param imChannelContext
* @return
* @author wchao
*/
- public static HttpResponse updateWebSocketProtocol(HttpRequest request, ChannelContext channelContext) {
+ public static HttpResponse updateWebSocketProtocol(HttpRequest request, ImChannelContext imChannelContext) {
Map headers = request.getHeaders();
- String Sec_WebSocket_Key = headers.get(HttpConst.RequestHeaderKey.Sec_WebSocket_Key);
+ String Sec_WebSocket_Key = headers.get(Http.RequestHeaderKey.Sec_WebSocket_Key);
if (StringUtils.isNotBlank(Sec_WebSocket_Key)) {
String Sec_WebSocket_Key_Magic = Sec_WebSocket_Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@@ -191,9 +191,9 @@ public class WsServerDecoder {
httpResponse.setStatus(HttpResponseStatus.C101);
Map respHeaders = new HashMap<>();
- respHeaders.put(HttpConst.ResponseHeaderKey.Connection, HttpConst.ResponseHeaderValue.Connection.Upgrade);
- respHeaders.put(HttpConst.ResponseHeaderKey.Upgrade, "WebSocket");
- respHeaders.put(HttpConst.ResponseHeaderKey.Sec_WebSocket_Accept, acceptKey);
+ respHeaders.put(Http.ResponseHeaderKey.Connection, Http.ResponseHeaderValue.Connection.Upgrade);
+ respHeaders.put(Http.ResponseHeaderKey.Upgrade, "WebSocket");
+ respHeaders.put(Http.ResponseHeaderKey.Sec_WebSocket_Accept, acceptKey);
httpResponse.setHeaders(respHeaders);
return httpResponse;
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsServerEncoder.java b/jim-common/src/main/java/org/jim/common/ws/WsServerEncoder.java
index accc120..bbbcf3f 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsServerEncoder.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsServerEncoder.java
@@ -2,10 +2,11 @@ package org.jim.common.ws;
import java.nio.ByteBuffer;
+import org.jim.common.ImChannelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
+import org.tio.core.TioConfig;
import org.tio.core.utils.ByteBufferUtils;
/**
@@ -34,8 +35,9 @@ public class WsServerEncoder {
}
}
- public static ByteBuffer encode(WsResponsePacket wsResponsePacket, GroupContext groupContext, ChannelContext channelContext) {
- byte[] imBody = wsResponsePacket.getBody();//就是ws的body,不包括ws的头
+ public static ByteBuffer encode(WsResponsePacket wsResponsePacket, ImChannelContext imChannelContext) {
+ //就是ws的body,不包括ws的头
+ byte[] imBody = wsResponsePacket.getBody();
int wsBodyLength = 0;
if (imBody != null) {
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsSessionContext.java b/jim-common/src/main/java/org/jim/common/ws/WsSessionContext.java
index b980e87..332a643 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsSessionContext.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsSessionContext.java
@@ -2,6 +2,7 @@ package org.jim.common.ws;
import java.util.List;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImSessionContext;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpResponse;
@@ -18,12 +19,12 @@ public class WsSessionContext extends ImSessionContext {
private boolean isHandshaked = false;
/**
- * websocket 握手请求包
+ * webSocket 握手请求包
*/
private HttpRequest handshakeRequestPacket = null;
/**
- * websocket 握手响应包
+ * webSocket 握手响应包
*/
private HttpResponse handshakeResponsePacket = null;
/**
@@ -33,20 +34,21 @@ public class WsSessionContext extends ImSessionContext {
/**
* ws响应状态包;
*/
- private WsResponsePacket wsResponsPacket = null;
+ private WsResponsePacket wsResponsePacket = null;
- //websocket 协议用到的,有时候数据包是分几个到的,注意那个fin字段,本im暂时不支持
+ /**
+ * webSocket 协议用到的,有时候数据包是分几个到的,注意那个fin字段,本im暂时不支持
+ */
private List lastParts = null;
/**
- *
*
* @author wchao
* 2017年2月21日 上午10:27:54
*
*/
- public WsSessionContext() {
-
+ public WsSessionContext(ImChannelContext imChannelContext) {
+ super(imChannelContext);
}
/**
@@ -85,7 +87,7 @@ public class WsSessionContext extends ImSessionContext {
}
/**
- * @param httpHandshakePacket the httpHandshakePacket to set
+ * @param handshakeRequestPacket the httpHandshakePacket to set
*/
public void setHandshakeRequestPacket(HttpRequest handshakeRequestPacket) {
this.handshakeRequestPacket = handshakeRequestPacket;
@@ -113,11 +115,11 @@ public class WsSessionContext extends ImSessionContext {
this.wsRequestPacket = wsRequestPacket;
}
- public WsResponsePacket getWsResponsPacket() {
- return wsResponsPacket;
+ public WsResponsePacket getWsResponsePacket() {
+ return wsResponsePacket;
}
- public void setWsResponsPacket(WsResponsePacket wsResponsPacket) {
- this.wsResponsPacket = wsResponsPacket;
+ public void setWsResponsePacket(WsResponsePacket wsResponsePacket) {
+ this.wsResponsePacket = wsResponsePacket;
}
}
diff --git a/jim-common/src/main/java/org/jim/common/ws/WsTioUuid.java b/jim-common/src/main/java/org/jim/common/ws/WsTioUuid.java
index 9801a37..ac4c87d 100644
--- a/jim-common/src/main/java/org/jim/common/ws/WsTioUuid.java
+++ b/jim-common/src/main/java/org/jim/common/ws/WsTioUuid.java
@@ -1,9 +1,9 @@
package org.jim.common.ws;
import org.tio.core.intf.TioUuid;
+import org.tio.utils.hutool.Snowflake;
-import cn.hutool.core.lang.Snowflake;
-import cn.hutool.core.util.RandomUtil;
+import java.util.concurrent.ThreadLocalRandom;
/**
* @author WChao
@@ -13,11 +13,11 @@ public class WsTioUuid implements TioUuid {
private Snowflake snowflake;
public WsTioUuid() {
- snowflake = new Snowflake(RandomUtil.randomInt(1, 30), RandomUtil.randomInt(1, 30));
+ snowflake = new Snowflake(ThreadLocalRandom.current().nextInt(1, 30), ThreadLocalRandom.current().nextInt(1, 30));
}
- public WsTioUuid(long workerId, long datacenterId) {
- snowflake = new Snowflake(workerId, datacenterId);
+ public WsTioUuid(long workerId, long dataCenterId) {
+ snowflake = new Snowflake(workerId, dataCenterId);
}
/**
diff --git a/jim-parent/pom.xml b/jim-parent/pom.xml
index 11884cf..be32881 100644
--- a/jim-parent/pom.xml
+++ b/jim-parent/pom.xml
@@ -5,7 +5,7 @@
jim-parent
pom
${project.artifactId}
- 2.6.0.v20190114-RELEASE
+ 3.0.0.v20200101-RELEASE
Jim-parent is the dependent parent project of J-IM communication establishment.
http://www.j-im.org/
@@ -34,9 +34,9 @@
../jim-server-demo
- 2.6.0.v20190114-RELEASE
- 2.4.0.v20180508-RELEASE
- 2.4.0.v20180508-RELEASE
+ 3.0.0.v20200101-RELEASE
+ 3.5.8.v20191228-RELEASE
+ 3.5.8.v20191228-RELEASE
UTF-8
UTF-8
@@ -62,6 +62,7 @@
2.7.3
3.7.0
2.3.21-release
+ 23.0
@@ -250,7 +251,7 @@
com.google.guava
guava
- 23.0
+ ${guava.version}
nl.basjes.parse.useragent
@@ -267,6 +268,11 @@
j2cache-core
${j2cache.version}
+
+ cn.hutool
+ hutool-all
+ ${hutool.version}
+
diff --git a/jim-server-demo/pom.xml b/jim-server-demo/pom.xml
index de38441..75f4d61 100644
--- a/jim-server-demo/pom.xml
+++ b/jim-server-demo/pom.xml
@@ -6,7 +6,7 @@
org.j-im
jim-parent
- 2.6.0.v20190114-RELEASE
+ 3.0.0.v20200101-RELEASE
../jim-parent/pom.xml
diff --git a/jim-server-demo/src/main/java/org/jim/server/demo/ImServerDemoStart.java b/jim-server-demo/src/main/java/org/jim/server/demo/ImServerDemoStart.java
index ca7d842..c6fc548 100644
--- a/jim-server-demo/src/main/java/org/jim/server/demo/ImServerDemoStart.java
+++ b/jim-server-demo/src/main/java/org/jim/server/demo/ImServerDemoStart.java
@@ -3,17 +3,16 @@
*/
package org.jim.server.demo;
-import com.jfinal.kit.PropKit;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConfig;
-import org.jim.common.ImConst;
-import org.jim.common.config.PropertyImConfigBuilder;
+import org.jim.common.config.ImConfig;
import org.jim.common.packets.Command;
import org.jim.common.utils.PropUtil;
import org.jim.server.ImServerStarter;
import org.jim.server.command.CommandManager;
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.jim.server.demo.command.DemoWsHandshakeProcessor;
import org.jim.server.demo.listener.ImDemoGroupListener;
import org.jim.server.demo.service.LoginServiceProcessor;
@@ -26,12 +25,12 @@ import org.tio.core.ssl.SslConfig;
public class ImServerDemoStart {
public static void main(String[] args)throws Exception{
- ImConfig imConfig = new PropertyImConfigBuilder("jim.properties").build();
+ ImServerConfig imServerConfig = new PropertyImServerConfigBuilder("jim.properties").build();
//初始化SSL;(开启SSL之前,你要保证你有SSL证书哦...)
- initSsl(imConfig);
+ initSsl(imServerConfig);
//设置群组监听器,非必须,根据需要自己选择性实现;
- imConfig.setImGroupListener(new ImDemoGroupListener());
- ImServerStarter imServerStarter = new ImServerStarter(imConfig);
+ imServerConfig.setImGroupListener(new ImDemoGroupListener());
+ ImServerStarter imServerStarter = new ImServerStarter(imServerConfig);
/*****************start 以下处理器根据业务需要自行添加与扩展,每个Command都可以添加扩展,此处为demo中处理**********************************/
HandshakeReqHandler handshakeReqHandler = CommandManager.getCommand(Command.COMMAND_HANDSHAKE_REQ, HandshakeReqHandler.class);
//添加自定义握手处理器;
@@ -45,19 +44,19 @@ public class ImServerDemoStart {
/**
* 开启SSL之前,你要保证你有SSL证书哦!
- * @param imConfig
+ * @param imServerConfig
* @throws Exception
*/
- private static void initSsl(ImConfig imConfig) throws Exception {
+ private static void initSsl(ImServerConfig imServerConfig) throws Exception {
//开启SSL
- if(ImConst.ON.equals(imConfig.getIsSSL())){
+ if(ImConfig.Const.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);
- imConfig.setSslConfig(sslConfig);
+ imServerConfig.setSslConfig(sslConfig);
}
}
}
diff --git a/jim-server-demo/src/main/java/org/jim/server/demo/command/DemoWsHandshakeProcessor.java b/jim-server-demo/src/main/java/org/jim/server/demo/command/DemoWsHandshakeProcessor.java
index c486538..ae9decc 100644
--- a/jim-server-demo/src/main/java/org/jim/server/demo/command/DemoWsHandshakeProcessor.java
+++ b/jim-server-demo/src/main/java/org/jim/server/demo/command/DemoWsHandshakeProcessor.java
@@ -3,9 +3,11 @@
*/
package org.jim.server.demo.command;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
-import org.jim.common.http.HttpConst;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpRequest;
import org.jim.common.packets.Command;
import org.jim.common.packets.LoginReqBody;
@@ -13,7 +15,6 @@ import org.jim.common.utils.JsonKit;
import org.jim.server.command.CommandManager;
import org.jim.server.command.handler.LoginReqHandler;
import org.jim.server.command.handler.processor.handshake.WsHandshakeProcessor;
-import org.tio.core.ChannelContext;
/**
* @author WChao
*
@@ -21,7 +22,7 @@ import org.tio.core.ChannelContext;
public class DemoWsHandshakeProcessor extends WsHandshakeProcessor {
@Override
- public void onAfterHandshaked(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public void onAfterHandshake(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
LoginReqHandler loginHandler = (LoginReqHandler)CommandManager.getCommand(Command.COMMAND_LOGIN_REQ);
HttpRequest request = (HttpRequest)packet;
String username = request.getParams().get("username") == null ? null : (String)request.getParams().get("username")[0];
@@ -30,10 +31,14 @@ public class DemoWsHandshakeProcessor extends WsHandshakeProcessor {
LoginReqBody loginBody = new LoginReqBody(username,password,token);
byte[] loginBytes = JsonKit.toJsonBytes(loginBody);
request.setBody(loginBytes);
- request.setBodyString(new String(loginBytes,HttpConst.CHARSET_NAME));
- ImPacket loginRespPacket = loginHandler.handler(request, channelContext);
+ try{
+ request.setBodyString(new String(loginBytes, ImConst.CHARSET));
+ }catch (Exception e){
+ throw new ImException(e);
+ }
+ ImPacket loginRespPacket = loginHandler.handler(request, imChannelContext);
if(loginRespPacket != null){
- ImAio.send(channelContext, loginRespPacket);
+ Jim.send(imChannelContext, loginRespPacket);
}
}
}
diff --git a/jim-server-demo/src/main/java/org/jim/server/demo/listener/ImDemoGroupListener.java b/jim-server-demo/src/main/java/org/jim/server/demo/listener/ImDemoGroupListener.java
index eb8a708..41e42c7 100644
--- a/jim-server-demo/src/main/java/org/jim/server/demo/listener/ImDemoGroupListener.java
+++ b/jim-server-demo/src/main/java/org/jim/server/demo/listener/ImDemoGroupListener.java
@@ -1,33 +1,40 @@
package org.jim.server.demo.listener;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.ImSessionContext;
+import org.jim.common.exception.ImException;
+import org.jim.common.listener.ImGroupListener;
import org.tio.core.ChannelContext;
import org.jim.common.packets.Client;
import org.jim.common.packets.Command;
import org.jim.common.packets.ExitGroupNotifyRespBody;
import org.jim.common.packets.RespBody;
import org.jim.common.packets.User;
-import org.jim.server.listener.ImGroupListener;
+
/**
* @author WChao
* 2017年5月13日 下午10:38:36
*/
-public class ImDemoGroupListener extends ImGroupListener{
- /**
+public class ImDemoGroupListener implements ImGroupListener {
+ @Override
+ public void onAfterBind(ImChannelContext imChannelContext, String group) throws ImException {
+ System.out.println("===绑定成功:"+group);
+ }
+
+ /**
* @param channelContext
* @param group
* @throws Exception
* @author: WChao
*/
@Override
- public void onAfterUnbind(ChannelContext channelContext, String group) throws Exception {
+ public void onAfterUnbind(ImChannelContext channelContext, String group) throws ImException {
//发退出房间通知 COMMAND_EXIT_GROUP_NOTIFY_RESP
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
ExitGroupNotifyRespBody exitGroupNotifyRespBody = new ExitGroupNotifyRespBody();
exitGroupNotifyRespBody.setGroup(group);
- Client client = imSessionContext.getClient();
+ Client client = channelContext.getSessionContext().getClient();
if(client == null){
return;
}
@@ -40,7 +47,7 @@ public class ImDemoGroupListener extends ImGroupListener{
RespBody respBody = new RespBody(Command.COMMAND_EXIT_GROUP_NOTIFY_RESP,exitGroupNotifyRespBody);
ImPacket imPacket = new ImPacket(Command.COMMAND_EXIT_GROUP_NOTIFY_RESP, respBody.toByte());
- ImAio.sendToGroup(group, imPacket);
+ Jim.sendToGroup(group, imPacket);
}
}
diff --git a/jim-server-demo/src/main/java/org/jim/server/demo/service/LoginServiceProcessor.java b/jim-server-demo/src/main/java/org/jim/server/demo/service/LoginServiceProcessor.java
index da1ba38..963c7c6 100644
--- a/jim-server-demo/src/main/java/org/jim/server/demo/service/LoginServiceProcessor.java
+++ b/jim-server-demo/src/main/java/org/jim/server/demo/service/LoginServiceProcessor.java
@@ -5,10 +5,7 @@ package org.jim.server.demo.service;
import cn.hutool.core.util.RandomUtil;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConst;
-import org.jim.common.ImPacket;
-import org.jim.common.ImSessionContext;
-import org.jim.common.ImStatus;
+import org.jim.common.*;
import org.jim.common.http.HttpConst;
import org.jim.common.packets.Command;
import org.jim.common.packets.Group;
@@ -51,17 +48,17 @@ public class LoginServiceProcessor implements LoginCmdProcessor {
/**
* 根据用户名和密码获取用户
- * @param loginname
+ * @param loginName
* @param password
* @return
* @author: WChao
*/
- public User getUser(String loginname, String password) {
- String text = loginname+password;
+ public User getUser(String loginName, String password) {
+ String text = loginName+password;
String key = ImConst.AUTH_KEY;
- String token = Md5.sign(text, key, HttpConst.CHARSET_NAME);
+ String token = Md5.sign(text, key, CHARSET);
User user = getUser(token);
- user.setId(loginname);
+ user.setId(loginName);
return user;
}
/**
@@ -124,17 +121,17 @@ public class LoginServiceProcessor implements LoginCmdProcessor {
* 当登陆失败时设置user属性需要为空,相反登陆成功user属性是必须非空的;
*/
@Override
- public LoginRespBody doLogin(LoginReqBody loginReqBody , ChannelContext channelContext) {
- String loginname = loginReqBody.getLoginname();
+ public LoginRespBody doLogin(LoginReqBody loginReqBody , ImChannelContext channelContext) {
+ String loginName = loginReqBody.getLoginname();
String password = loginReqBody.getPassword();
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = channelContext.getSessionContext();
String handshakeToken = imSessionContext.getToken();
User user;
LoginRespBody loginRespBody;
if (!StringUtils.isBlank(handshakeToken)) {
user = this.getUser(handshakeToken);
}else{
- user = this.getUser(loginname, password);
+ user = this.getUser(loginName, password);
}
if(user == null){
loginRespBody = new LoginRespBody(Command.COMMAND_LOGIN_RESP,ImStatus.C10008);
@@ -145,12 +142,13 @@ public class LoginServiceProcessor implements LoginCmdProcessor {
}
@Override
- public void onSuccess(ChannelContext channelContext) {
+ public void onSuccess(ImChannelContext channelContext) {
logger.info("登录成功回调方法");
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = channelContext.getSessionContext();
User user = imSessionContext.getClient().getUser();
if(user.getGroups() != null){
- for(Group group : user.getGroups()){//发送加入群组通知
+ //发送加入群组通知
+ for(Group group : user.getGroups()){
ImPacket groupPacket = new ImPacket(Command.COMMAND_JOIN_GROUP_REQ,JsonKit.toJsonBytes(group));
try {
JoinGroupReqHandler joinGroupReqHandler = CommandManager.getCommand(Command.COMMAND_JOIN_GROUP_REQ, JoinGroupReqHandler.class);
@@ -163,7 +161,7 @@ public class LoginServiceProcessor implements LoginCmdProcessor {
}
@Override
- public boolean isProtocol(ChannelContext channelContext) {
+ public boolean isProtocol(ImChannelContext channelContext) {
return true;
}
diff --git a/jim-server/pom.xml b/jim-server/pom.xml
index 8562b3e..c3f091d 100644
--- a/jim-server/pom.xml
+++ b/jim-server/pom.xml
@@ -7,7 +7,7 @@
org.j-im
jim-parent
- 2.6.0.v20190114-RELEASE
+ 3.0.0.v20200101-RELEASE
../jim-parent/pom.xml
diff --git a/jim-server/src/main/java/org/jim/server/ImServerChannelContext.java b/jim-server/src/main/java/org/jim/server/ImServerChannelContext.java
new file mode 100644
index 0000000..bc12bc8
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/ImServerChannelContext.java
@@ -0,0 +1,45 @@
+package org.jim.server;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImHandler;
+import org.jim.common.config.ImConfig;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.protocol.IProtocol;
+import org.jim.server.handler.AbstractProtocolHandler;
+import org.tio.core.ChannelContext;
+import org.tio.utils.thread.pool.AbstractQueueRunnable;
+
+/**
+ * @ClassName ImServerChannelContext
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/5 23:56
+ * @Version 1.0
+ **/
+public class ImServerChannelContext extends ImChannelContext {
+
+ protected AbstractQueueRunnable msgQue;
+
+ protected AbstractProtocolHandler protocolHandler;
+
+ public ImServerChannelContext(ImConfig imConfig, ChannelContext tioChannelContext) {
+ super(imConfig, tioChannelContext);
+ }
+
+ public AbstractQueueRunnable getMsgQue() {
+ return msgQue;
+ }
+
+ public void setMsgQue(AbstractQueueRunnable msgQue) {
+ this.msgQue = msgQue;
+ }
+
+ public AbstractProtocolHandler getProtocolHandler() {
+ return protocolHandler;
+ }
+
+ public void setProtocolHandler(AbstractProtocolHandler protocolHandler) {
+ this.protocolHandler = protocolHandler;
+ }
+
+}
diff --git a/jim-server/src/main/java/org/jim/server/ImServerGroupContext.java b/jim-server/src/main/java/org/jim/server/ImServerGroupContext.java
index 76a3599..7bace9a 100644
--- a/jim-server/src/main/java/org/jim/server/ImServerGroupContext.java
+++ b/jim-server/src/main/java/org/jim/server/ImServerGroupContext.java
@@ -3,31 +3,19 @@
*/
package org.jim.server;
-import org.jim.common.ImConst;
-import org.jim.common.ImAio;
-import org.jim.common.ImConfig;
-import org.jim.common.cache.redis.RedissonTemplate;
-import org.jim.common.cluster.redis.RedisCluster;
-import org.jim.common.cluster.redis.RedisClusterConfig;
-import org.jim.server.command.CommandManager;
-import org.jim.server.handler.ImServerAioHandler;
-import org.jim.server.handler.ProtocolHandlerManager;
-import org.jim.server.listener.ImServerAioListener;
+import org.jim.common.config.ImConfig;
+import org.jim.server.handler.ImServerHandler;
+import org.jim.server.listener.ImServerListenerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.server.ServerGroupContext;
-import org.tio.utils.Threads;
-import org.tio.utils.thread.pool.DefaultThreadFactory;
import org.tio.utils.thread.pool.SynThreadPoolExecutor;
-import java.util.concurrent.LinkedBlockingQueue;
-
/**
*
* @author WChao
*
*/
-public class ImServerGroupContext extends ServerGroupContext{
+public class ImServerGroupContext /*extends TioConfig */{
private Logger log = LoggerFactory.getLogger(ImServerGroupContext.class);
@@ -39,8 +27,8 @@ public class ImServerGroupContext extends ServerGroupContext{
protected SynThreadPoolExecutor timExecutor = null;
- public ImServerGroupContext(ImConfig imConfig , ImServerAioHandler imServerAioHandler,ImServerAioListener imServerAioListener) {
- super(imServerAioHandler, imServerAioListener);
+ public ImServerGroupContext(ImConfig imConfig , ImServerHandler imServerAioHandler, ImServerListenerAdapter imServerAioListener) {
+ /*super(imServerAioHandler, imServerAioListener);
this.imConfig = imConfig;
this.setHeartbeatTimeout(imConfig.getHeartbeatTimeout());
//是否开启集群
@@ -67,7 +55,7 @@ public class ImServerGroupContext extends ServerGroupContext{
imConfig.setGroupContext(this);
ProtocolHandlerManager.init(imConfig);
CommandManager.init(imConfig);
- ImAio.imConfig = imConfig;
+ Jim.imConfig = imConfig;*/
}
public SynThreadPoolExecutor getTimExecutor() {
diff --git a/jim-server/src/main/java/org/jim/server/ImServerStarter.java b/jim-server/src/main/java/org/jim/server/ImServerStarter.java
index 1802124..733ff42 100644
--- a/jim-server/src/main/java/org/jim/server/ImServerStarter.java
+++ b/jim-server/src/main/java/org/jim/server/ImServerStarter.java
@@ -4,72 +4,60 @@
package org.jim.server;
import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
-import org.jim.server.handler.ImServerAioHandler;
+import org.jim.common.cache.redis.RedissonTemplate;
+import org.jim.common.cluster.redis.RedisCluster;
+import org.jim.common.cluster.redis.RedisClusterConfig;
+import org.jim.common.config.ImConfig;
+import org.jim.server.config.ImServerConfig;
+import org.jim.server.handler.ProtocolManager;
import org.jim.server.helper.redis.RedisMessageHelper;
-import org.jim.server.listener.ImGroupListener;
-import org.jim.server.listener.ImServerAioListener;
-import org.tio.core.intf.GroupListener;
-import org.tio.core.ssl.SslConfig;
-import org.tio.server.AioServer;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tio.server.ServerTioConfig;
+import org.tio.server.TioServer;
import java.io.IOException;
/**
- *
+ * J-IM服务端启动类
* @author WChao
*
*/
public class ImServerStarter {
-
- private ImServerAioHandler imAioHandler = null;
- private ImServerAioListener imAioListener = null;
- private ImServerGroupContext imServerGroupContext = null;
- private ImGroupListener imGroupListener = null;
- private AioServer aioServer = null;
- private ImConfig imConfig = null;
-
- public ImServerStarter(ImConfig imConfig){
- this(imConfig,null);
+
+ private static Logger log = LoggerFactory.getLogger(ImServerStarter.class);
+ private TioServer tioServer = null;
+ private ImServerConfig imServerConfig;
+
+ public ImServerStarter(ImServerConfig imServerConfig){
+ this.imServerConfig = imServerConfig;
+ init(imServerConfig);
}
- public ImServerStarter(ImConfig imConfig,ImServerAioListener imAioListener){
- this.imConfig = imConfig;
- this.imAioListener = imAioListener;
- init();
- }
-
- public void init(){
- System.setProperty("tio.default.read.buffer.size", String.valueOf(imConfig.getReadBufferSize()));
- imAioHandler = new ImServerAioHandler(imConfig) ;
- if(imAioListener == null){
- imAioListener = new ImServerAioListener(imConfig);
+ public void init(ImServerConfig imServerConfig){
+ ImConfig.Global.set(imServerConfig);
+ System.setProperty("tio.default.read.buffer.size", String.valueOf(imServerConfig.getReadBufferSize()));
+ if(imServerConfig.getMessageHelper() == null){
+ imServerConfig.setMessageHelper(new RedisMessageHelper());
}
- GroupListener groupListener = imConfig.getImGroupListener();
- if(groupListener == null){
- imConfig.setImGroupListener(new ImGroupListener());
- }
- this.imGroupListener = (ImGroupListener)imConfig.getImGroupListener();
- imServerGroupContext = new ImServerGroupContext(imConfig,imAioHandler, imAioListener);
- imServerGroupContext.setGroupListener(imGroupListener);
- if(imConfig.getMessageHelper() == null){
- imConfig.setMessageHelper(new RedisMessageHelper(imConfig));
- }
- //开启SSL
- if(ImConst.ON.equals(imConfig.getIsSSL())){
- SslConfig sslConfig = imConfig.getSslConfig();
- if(sslConfig != null) {
- imServerGroupContext.setSslConfig(sslConfig);
+ if(ImConfig.Const.ON.equals(imServerConfig.getIsCluster())){
+ imServerConfig.setIsStore(ImConfig.Const.ON);
+ if(imServerConfig.getCluster() == null){
+ try{
+ imServerConfig.setCluster(new RedisCluster(RedisClusterConfig.newInstance(ImConst.Topic.REDIS_CLUSTER_TOPIC_SUFFIX, RedissonTemplate.me().getRedissonClient())));
+ }catch(Exception e){
+ log.error("连接集群配置出现异常,请检查!",e);
+ }
}
}
- aioServer = new AioServer(imServerGroupContext);
+ ProtocolManager.init();
+ tioServer = new TioServer((ServerTioConfig)imServerConfig.getTioConfig());
}
public void start() throws IOException {
- aioServer.start(this.imConfig.getBindIp(),this.imConfig.getBindPort());
+ tioServer.start(this.imServerConfig.getBindIp(), this.imServerConfig.getBindPort());
}
public void stop(){
- aioServer.stop();
+ tioServer.stop();
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/AbstractCmdHandler.java b/jim-server/src/main/java/org/jim/server/command/AbstractCmdHandler.java
index 1b90edc..230a67a 100644
--- a/jim-server/src/main/java/org/jim/server/command/AbstractCmdHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/AbstractCmdHandler.java
@@ -3,24 +3,21 @@
*/
package org.jim.server.command;
-import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
-import org.jim.common.ImConfig;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.config.ImConfig;
import org.jim.server.command.handler.processor.CmdProcessor;
-import org.tio.core.ChannelContext;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import org.jim.server.config.ImServerConfig;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Set;
/**
* 版本: [1.0]
* 功能说明:
* @author: WChao 创建时间: 2017年9月11日 下午2:07:44
*/
-public abstract class AbstractCmdHandler implements CmdHandler {
+public abstract class AbstractCmdHandler implements CmdHandler, ImConst {
/**
* 不同协议cmd处理命令如(ws、socket、自定义协议)握手、心跳命令等.
*/
@@ -28,14 +25,10 @@ public abstract class AbstractCmdHandler implements CmdHandler {
/**
* IM相关配置类
*/
- protected ImConfig imConfig;
+ protected ImServerConfig imConfig = ImConfig.Global.get();
public AbstractCmdHandler() {};
- public AbstractCmdHandler(ImConfig imConfig) {
- this.imConfig = imConfig;
- }
-
public AbstractCmdHandler addProcessor(CmdProcessor processor){
this.processors.put(processor.name(), processor);
return this;
@@ -43,16 +36,16 @@ public abstract class AbstractCmdHandler implements CmdHandler {
/**
* 根据当前通道所属协议获取cmd业务处理器
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public List getProcessor(ChannelContext channelContext,Class clazz){
+ public List getProcessor(ImChannelContext imChannelContext, Class clazz){
List processorList = null;
for(Entry processorEntry : processors.entrySet()){
CmdProcessor processor = processorEntry.getValue();
- if(processor.isProtocol(channelContext)){
+ if(processor.isProtocol(imChannelContext)){
if(CollectionUtils.isEmpty(processorList)){
- processorList = Lists.newArrayList();
+ processorList = new ArrayList<>();
}
processorList.add((T)processor);
}
@@ -71,7 +64,7 @@ public abstract class AbstractCmdHandler implements CmdHandler {
CmdProcessor processor = processorEntry.getValue();
if(name.equals(processor.name())){
if(CollectionUtils.isEmpty(processorList)){
- processorList = Lists.newArrayList();
+ processorList = new ArrayList<>();
}
processorList.add((T)processor);
}
@@ -89,7 +82,7 @@ public abstract class AbstractCmdHandler implements CmdHandler {
for(Entry processorEntry : processors.entrySet()){
CmdProcessor processor = processorEntry.getValue();
if(CollectionUtils.isEmpty(processorList)){
- processorList = Lists.newArrayList();
+ processorList = new ArrayList<>();
}
if(CollectionUtils.isEmpty(names)){
processorList.add((T)processor);
@@ -105,13 +98,9 @@ public abstract class AbstractCmdHandler implements CmdHandler {
return processors.remove(name);
}
-
- public ImConfig getImConfig() {
+
+ public ImServerConfig getImConfig() {
return imConfig;
}
- public void setImConfig(ImConfig imConfig) {
- this.imConfig = imConfig;
- }
-
}
diff --git a/jim-server/src/main/java/org/jim/server/command/CmdHandler.java b/jim-server/src/main/java/org/jim/server/command/CmdHandler.java
index bcfe8c1..9fbfa66 100644
--- a/jim-server/src/main/java/org/jim/server/command/CmdHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/CmdHandler.java
@@ -1,29 +1,31 @@
package org.jim.server.command;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.tio.core.ChannelContext;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.Command;
/**
*
* 版本: [1.0]
* 功能说明:
- * 作者: WChao 创建时间: 2017年9月8日 下午4:29:38
+ * @author : WChao 创建时间: 2017年9月8日 下午4:29:38
*/
public interface CmdHandler
{
/**
* 功能描述:[命令主键]
- * 创建者:WChao 创建时间: 2017年7月17日 下午2:31:51
+ * @author:WChao 创建时间: 2017年7月17日 下午2:31:51
* @return
*/
- public Command command();
+ Command command();
/**
- * @param packet
- * @param channelContext
+ * 处理Cmd命令
+ * @param imPacket
+ * @param imChannelContext
* @return
- * @throws Exception
+ * @throws ImException
* @date 2016年11月18日 下午1:08:45
*/
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception;
+ ImPacket handler(ImPacket imPacket, ImChannelContext imChannelContext) throws ImException;
}
diff --git a/jim-server/src/main/java/org/jim/server/command/CommandManager.java b/jim-server/src/main/java/org/jim/server/command/CommandManager.java
index 85304f8..6b35e85 100644
--- a/jim-server/src/main/java/org/jim/server/command/CommandManager.java
+++ b/jim-server/src/main/java/org/jim/server/command/CommandManager.java
@@ -3,9 +3,9 @@
*/
package org.jim.server.command;
-import org.jim.common.ImConfig;
import org.jim.common.packets.Command;
import org.jim.server.command.handler.processor.CmdProcessor;
+import org.jim.server.config.ImServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,9 +24,7 @@ public class CommandManager{
*/
private static Map handlerMap = new HashMap<>();
private static Logger LOG = LoggerFactory.getLogger(CommandManager.class);
-
- private static ImConfig imConfig;
-
+
private CommandManager(){};
static{
@@ -63,7 +61,6 @@ public class CommandManager{
}
if(handlerMap.get(cmd_number) == null)
{
- imCommandHandler.setImConfig(imConfig);
return handlerMap.put(cmd_number,imCommandHandler);
}
return null;
@@ -95,18 +92,4 @@ public class CommandManager{
}
return handlerMap.get(command.getNumber());
}
-
- public static void init(ImConfig config) {
- imConfig = config;
- for(Entry entry : handlerMap.entrySet()){
- try {
- entry.getValue().setImConfig(imConfig);
- } catch (Exception e) {
- LOG.error(e.toString());
- }
- }
- }
- public static ImConfig getImConfig() {
- return imConfig;
- }
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/AuthReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/AuthReqHandler.java
index 3eb0a41..e6c9846 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/AuthReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/AuthReqHandler.java
@@ -1,15 +1,18 @@
package org.jim.server.command.handler;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
-import org.tio.core.ChannelContext;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.AuthReqBody;
import org.jim.common.packets.Command;
import org.jim.common.packets.RespBody;
import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.command.AbstractCmdHandler;
+import org.jim.server.handler.ProtocolManager;
+
/**
*
* 版本: [1.0]
@@ -19,11 +22,11 @@ import org.jim.server.command.AbstractCmdHandler;
public class AuthReqHandler extends AbstractCmdHandler
{
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception
+ public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException
{
if (packet.getBody() == null) {
RespBody respBody = new RespBody(Command.COMMAND_AUTH_RESP,ImStatus.C10010);
- return ImKit.ConvertRespPacket(respBody, channelContext);
+ return ProtocolManager.Converter.respPacket(respBody, channelContext);
}
AuthReqBody authReqBody = JsonKit.toBean(packet.getBody(), AuthReqBody.class);
String token = authReqBody.getToken() == null ? "" : authReqBody.getToken();
@@ -31,7 +34,7 @@ public class AuthReqHandler extends AbstractCmdHandler
authReqBody.setToken(data);
authReqBody.setCmd(null);
RespBody respBody = new RespBody(Command.COMMAND_AUTH_RESP,ImStatus.C10009).setData(authReqBody);
- return ImKit.ConvertRespPacket(respBody, channelContext);
+ return ProtocolManager.Converter.respPacket(respBody, channelContext);
}
@Override
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java
index ad96571..a6c337a 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java
@@ -1,21 +1,18 @@
package org.jim.server.command.handler;
-import com.google.common.collect.Sets;
-import org.apache.commons.collections4.CollectionUtils;
-import org.jim.common.ImAio;
-import org.jim.common.ImConst;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.ChatBody;
import org.jim.common.packets.ChatType;
import org.jim.common.packets.Command;
import org.jim.common.packets.RespBody;
import org.jim.common.utils.ChatKit;
+import org.jim.server.ImServerChannelContext;
import org.jim.server.command.AbstractCmdHandler;
-import org.jim.server.command.handler.processor.chat.ChatCmdProcessor;
-import org.jim.server.command.handler.processor.chat.MsgQueueRunnable;
-import org.tio.core.ChannelContext;
-
-import java.util.List;
+import org.jim.server.handler.ProtocolManager;
+import org.tio.utils.thread.pool.AbstractQueueRunnable;
/**
* 版本: [1.0]
@@ -25,26 +22,27 @@ import java.util.List;
public class ChatReqHandler extends AbstractCmdHandler {
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)channelContext;
if (packet.getBody() == null) {
- throw new Exception("body is null");
+ throw new ImException("body is null");
}
ChatBody chatBody = ChatKit.toChatBody(packet.getBody(), channelContext);
packet.setBody(chatBody.toByte());
//聊天数据格式不正确
if(chatBody == null || chatBody.getChatType() == null){
- ImPacket respChatPacket = ChatKit.dataInCorrectRespPacket(channelContext);
+ ImPacket respChatPacket = ProtocolManager.Packet.dataInCorrect(channelContext);
return respChatPacket;
}
- List chatProcessors = this.getProcessorNotEqualName(Sets.newHashSet(ImConst.BASE_ASYNC_CHAT_MESSAGE_PROCESSOR),ChatCmdProcessor.class);
+ /*List chatProcessors = this.getProcessorNotEqualName(new HashSet<>(ImConst.BASE_ASYNC_CHAT_MESSAGE_PROCESSOR),ChatCmdProcessor.class);
if(CollectionUtils.isNotEmpty(chatProcessors)){
chatProcessors.forEach(chatProcessor -> chatProcessor.handler(packet,channelContext));
- }
+ }*/
//异步调用业务处理消息接口
if(ChatType.forNumber(chatBody.getChatType()) != null){
- MsgQueueRunnable msgQueueRunnable = (MsgQueueRunnable)channelContext.getAttribute(ImConst.CHAT_QUEUE);
+ AbstractQueueRunnable msgQueueRunnable = imServerChannelContext.getMsgQue();
msgQueueRunnable.addMsg(packet);
- msgQueueRunnable.getExecutor().execute(msgQueueRunnable);
+ msgQueueRunnable.executor.execute(msgQueueRunnable);
}
ImPacket chatPacket = new ImPacket(Command.COMMAND_CHAT_REQ,new RespBody(Command.COMMAND_CHAT_REQ,chatBody).toByte());
//设置同步序列号;
@@ -53,19 +51,19 @@ public class ChatReqHandler extends AbstractCmdHandler {
if(ChatType.CHAT_TYPE_PRIVATE.getNumber() == chatBody.getChatType()){
String toId = chatBody.getTo();
if(ChatKit.isOnline(toId,imConfig)){
- ImAio.sendToUser(toId, chatPacket);
+ Jim.sendToUser(toId, chatPacket);
//发送成功响应包
- return ChatKit.sendSuccessRespPacket(channelContext);
+ return ProtocolManager.Packet.success(channelContext);
}else{
//用户不在线响应包
- return ChatKit.offlineRespPacket(channelContext);
+ return ProtocolManager.Packet.offline(channelContext);
}
//群聊
}else if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == chatBody.getChatType()){
String group_id = chatBody.getGroup_id();
- ImAio.sendToGroup(group_id, chatPacket);
+ Jim.sendToGroup(group_id, chatPacket);
//发送成功响应包
- return ChatKit.sendSuccessRespPacket(channelContext);
+ return ProtocolManager.Packet.success(channelContext);
}
return null;
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java
index c845055..3883635 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java
@@ -1,15 +1,17 @@
package org.jim.server.command.handler;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.CloseReqBody;
import org.jim.common.packets.Command;
import org.jim.common.packets.RespBody;
import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.command.AbstractCmdHandler;
-import org.tio.core.ChannelContext;
+import org.jim.server.handler.ProtocolManager;
/**
* 版本: [1.0]
@@ -19,22 +21,23 @@ import org.tio.core.ChannelContext;
public class CloseReqHandler extends AbstractCmdHandler
{
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws ImException
{
CloseReqBody closeReqBody = null;
try{
closeReqBody = JsonKit.toBean(packet.getBody(),CloseReqBody.class);
}catch (Exception e) {
//关闭请求消息格式不正确
- return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10020), channelContext);
+ return ProtocolManager.Converter.respPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10020), imChannelContext);
}
+ Jim.bSend(imChannelContext, ProtocolManager.Converter.respPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10021), imChannelContext));
if(closeReqBody == null || closeReqBody.getUserid() == null){
- ImAio.remove(channelContext, "收到关闭请求");
+ Jim.remove(imChannelContext, "收到关闭请求");
}else{
String userId = closeReqBody.getUserid();
- ImAio.remove(userId, "收到关闭请求!");
+ Jim.remove(userId, "收到关闭请求!");
}
- return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10021), channelContext);
+ return null;
}
@Override
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/HandshakeReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/HandshakeReqHandler.java
index 1522d6b..6ee95b1 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/HandshakeReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/HandshakeReqHandler.java
@@ -1,16 +1,15 @@
package org.jim.server.command.handler;
import org.apache.commons.collections4.CollectionUtils;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpRequest;
import org.jim.common.packets.Command;
import org.jim.common.ws.WsSessionContext;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.handler.processor.handshake.HandshakeCmdProcessor;
-import org.tio.core.Aio;
-import org.tio.core.ChannelContext;
-
import java.util.List;
/**
@@ -21,22 +20,22 @@ import java.util.List;
public class HandshakeReqHandler extends AbstractCmdHandler {
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
List handshakeProcessors = this.getProcessor(channelContext,HandshakeCmdProcessor.class);
if(CollectionUtils.isEmpty(handshakeProcessors)){
- Aio.remove(channelContext, "没有对应的握手协议处理器HandshakeProCmd...");
+ Jim.remove(channelContext, "没有对应的握手协议处理器HandshakeProCmd...");
return null;
}
HandshakeCmdProcessor handShakeProCmdHandler = handshakeProcessors.get(0);
ImPacket handShakePacket = handShakeProCmdHandler.handshake(packet, channelContext);
if (handShakePacket == null) {
- Aio.remove(channelContext, "业务层不同意握手");
+ Jim.remove(channelContext, "业务层不同意握手");
return null;
}
- ImAio.send(channelContext, handShakePacket);
- WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getAttribute();
+ Jim.send(channelContext, handShakePacket);
+ WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getSessionContext();
HttpRequest request = wsSessionContext.getHandshakeRequestPacket();
- handShakeProCmdHandler.onAfterHandshaked(request, channelContext);
+ handShakeProCmdHandler.onAfterHandshake(request, channelContext);
return null;
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/HeartbeatReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/HeartbeatReqHandler.java
index 6476876..2f754fb 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/HeartbeatReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/HeartbeatReqHandler.java
@@ -1,13 +1,13 @@
package org.jim.server.command.handler;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.jim.common.Protocol;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.Command;
import org.jim.common.packets.HeartbeatBody;
import org.jim.common.packets.RespBody;
-import org.jim.common.utils.ImKit;
import org.jim.server.command.AbstractCmdHandler;
-import org.tio.core.ChannelContext;
+import org.jim.server.handler.ProtocolManager;
/**
*
@@ -15,10 +15,10 @@ import org.tio.core.ChannelContext;
public class HeartbeatReqHandler extends AbstractCmdHandler
{
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception
+ public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException
{
RespBody heartbeatBody = new RespBody(Command.COMMAND_HEARTBEAT_REQ).setData(new HeartbeatBody(Protocol.HEARTBEAT_BYTE));
- ImPacket heartbeatPacket = ImKit.ConvertRespPacket(heartbeatBody,channelContext);
+ ImPacket heartbeatPacket = ProtocolManager.Converter.respPacket(heartbeatBody,channelContext);
return heartbeatPacket;
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/JoinGroupReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/JoinGroupReqHandler.java
index 3f03961..b72db0c 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/JoinGroupReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/JoinGroupReqHandler.java
@@ -2,15 +2,12 @@ package org.jim.server.command.handler;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImAio;
-import org.jim.common.ImPacket;
-import org.jim.common.ImSessionContext;
-import org.jim.common.ImStatus;
+import org.jim.common.*;
+import org.jim.common.exception.ImException;
import org.jim.server.command.handler.processor.group.GroupCmdProcessor;
+import org.jim.server.handler.ProtocolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
-import org.tio.core.ChannelContext;
import org.jim.common.packets.Command;
import org.jim.common.packets.Group;
import org.jim.common.packets.JoinGroupNotifyRespBody;
@@ -18,10 +15,8 @@ import org.jim.common.packets.JoinGroupRespBody;
import org.jim.common.packets.JoinGroupResult;
import org.jim.common.packets.RespBody;
import org.jim.common.packets.User;
-import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.command.AbstractCmdHandler;
-
import java.util.List;
/**
@@ -35,20 +30,20 @@ public class JoinGroupReqHandler extends AbstractCmdHandler {
private static Logger log = LoggerFactory.getLogger(JoinGroupReqHandler.class);
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
//绑定群组;
- ImPacket joinGroupRespPacket = bindGroup(packet, channelContext);
+ ImPacket joinGroupRespPacket = bindGroup(packet, imChannelContext);
//发送进房间通知;
- joinGroupNotify(packet,channelContext);
+ joinGroupNotify(packet,imChannelContext);
return joinGroupRespPacket;
}
/**
* 发送进房间通知;
* @param packet
- * @param channelContext
+ * @param imChannelContext
*/
- public void joinGroupNotify(ImPacket packet,ChannelContext channelContext){
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ public void joinGroupNotify(ImPacket packet, ImChannelContext imChannelContext)throws ImException{
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
User clientUser = imSessionContext.getClient().getUser();
User notifyUser = new User(clientUser.getId(),clientUser.getNick());
@@ -56,55 +51,52 @@ public class JoinGroupReqHandler extends AbstractCmdHandler {
Group joinGroup = JsonKit.toBean(packet.getBody(),Group.class);
String groupId = joinGroup.getGroup_id();
//发进房间通知 COMMAND_JOIN_GROUP_NOTIFY_RESP
- JoinGroupNotifyRespBody joinGroupNotifyRespBody = new JoinGroupNotifyRespBody().setGroup(groupId).setUser(notifyUser);
- RespBody notifyRespBody = new RespBody(Command.COMMAND_JOIN_GROUP_NOTIFY_RESP,joinGroupNotifyRespBody);
-
- ImPacket joinGroupNotifyRespPacket = new ImPacket(Command.COMMAND_JOIN_GROUP_NOTIFY_RESP,notifyRespBody.toByte());
- ImAio.sendToGroup(groupId, joinGroupNotifyRespPacket);
+ JoinGroupNotifyRespBody joinGroupNotifyRespBody = new JoinGroupNotifyRespBody(Command.COMMAND_JOIN_GROUP_NOTIFY_RESP, ImStatus.C10011)
+ .setGroup(groupId)
+ .setUser(notifyUser);
+ Jim.sendToGroup(groupId, ProtocolManager.Converter.respPacket(joinGroupNotifyRespBody,imChannelContext));
}
/**
* 绑定群组
* @param packet
- * @param channelContext
+ * @param imChannelContext
* @return
- * @throws Exception
+ * @throws ImException
*/
- public ImPacket bindGroup(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket bindGroup(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
if (packet.getBody() == null) {
- throw new Exception("body is null");
+ throw new ImException("body is null");
}
Group joinGroup = JsonKit.toBean(packet.getBody(),Group.class);
String groupId = joinGroup.getGroup_id();
if (StringUtils.isBlank(groupId)) {
- log.error("group is null,{}", channelContext);
- Aio.close(channelContext, "group is null when join group");
+ log.error("group is null,{}", imChannelContext);
+ Jim.close(imChannelContext, "group is null when join group");
return null;
}
//实际绑定之前执行处理器动作
- List groupCmdProcessors = this.getProcessor(channelContext, GroupCmdProcessor.class);
+ List groupCmdProcessors = this.getProcessor(imChannelContext, GroupCmdProcessor.class);
- //先定义为操作成功
- JoinGroupResult joinGroupResult = JoinGroupResult.JOIN_GROUP_RESULT_OK;
- JoinGroupRespBody joinGroupRespBody = new JoinGroupRespBody();
+ JoinGroupRespBody joinGroupRespBody = new JoinGroupRespBody(Command.COMMAND_JOIN_GROUP_RESP,ImStatus.C10011);
//当有群组处理器时候才会去处理
if(CollectionUtils.isNotEmpty(groupCmdProcessors)){
GroupCmdProcessor groupCmdProcessor = groupCmdProcessors.get(0);
- joinGroupRespBody = groupCmdProcessor.join(joinGroup, channelContext);
+ joinGroupRespBody = groupCmdProcessor.join(joinGroup, imChannelContext);
if (joinGroupRespBody == null || JoinGroupResult.JOIN_GROUP_RESULT_OK.getNumber() != joinGroupRespBody.getResult().getNumber()) {
RespBody joinRespBody = new RespBody(Command.COMMAND_JOIN_GROUP_RESP, ImStatus.C10012).setData(joinGroupRespBody);
- ImPacket respPacket = ImKit.ConvertRespPacket(joinRespBody, channelContext);
+ ImPacket respPacket = ProtocolManager.Converter.respPacket(joinRespBody, imChannelContext);
return respPacket;
}
}
//处理完处理器内容后
- ImAio.bindGroup(channelContext, groupId,imConfig.getMessageHelper().getBindListener());
+ Jim.bindGroup(imChannelContext, groupId);
//回一条消息,告诉对方进群结果
joinGroupRespBody.setGroup(groupId);
- joinGroupRespBody.setResult(joinGroupResult);
-
- RespBody joinRespBody = new RespBody(Command.COMMAND_JOIN_GROUP_RESP,ImStatus.C10011).setData(joinGroupRespBody);
- ImPacket respPacket = ImKit.ConvertRespPacket(joinRespBody, channelContext);
+ //先定义为操作成功
+ joinGroupRespBody.setResult(JoinGroupResult.JOIN_GROUP_RESULT_OK);
+ joinGroupRespBody.setData(joinGroupRespBody);
+ ImPacket respPacket = ProtocolManager.Converter.respPacket(joinGroupRespBody, imChannelContext);
return respPacket;
}
@Override
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/LoginReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/LoginReqHandler.java
index 8976c3d..0a1ee42 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/LoginReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/LoginReqHandler.java
@@ -1,11 +1,9 @@
package org.jim.server.command.handler;
import org.apache.commons.collections4.CollectionUtils;
-import org.jim.common.ImConst;
-import org.jim.common.ImAio;
-import org.jim.common.ImPacket;
-import org.jim.common.ImSessionContext;
-import org.jim.common.ImStatus;
+import org.jim.common.*;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImException;
import org.jim.common.message.MessageHelper;
import org.jim.common.packets.Command;
import org.jim.common.packets.Group;
@@ -15,13 +13,15 @@ import org.jim.common.packets.User;
import org.jim.common.protocol.IProtocol;
import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
+import org.jim.server.ImServerChannelContext;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.CommandManager;
import org.jim.server.command.handler.processor.login.LoginCmdProcessor;
+import org.jim.server.handler.ProtocolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
import org.tio.core.ChannelContext;
+import org.tio.core.Tio;
import java.util.List;
@@ -34,22 +34,23 @@ public class LoginReqHandler extends AbstractCmdHandler {
private static Logger log = LoggerFactory.getLogger(LoginReqHandler.class);
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)imChannelContext;
if (packet.getBody() == null) {
- Aio.remove(channelContext, "body is null");
+ Jim.remove(imChannelContext, "body is null");
return null;
}
- List loginProcessors = this.getProcessor(channelContext, LoginCmdProcessor.class);
+ List loginProcessors = this.getProcessor(imChannelContext, LoginCmdProcessor.class);
if(CollectionUtils.isEmpty(loginProcessors)){
log.info("登录失败,没有登录命令业务处理器!");
- Aio.remove(channelContext, "no login serviceHandler processor!");
+ Jim.remove(imChannelContext, "no login serviceHandler processor!");
return null;
}
LoginCmdProcessor loginServiceHandler = loginProcessors.get(0);
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
LoginReqBody loginReqBody = JsonKit.toBean(packet.getBody(),LoginReqBody.class);
- LoginRespBody loginRespBody = loginServiceHandler.doLogin(loginReqBody,channelContext);
+ LoginRespBody loginRespBody = loginServiceHandler.doLogin(loginReqBody, imChannelContext);
if (loginRespBody == null || loginRespBody.getUser() == null) {
log.info("登录失败, loginName:{}, password:{}", loginReqBody.getLoginname(), loginReqBody.getPassword());
if(loginRespBody == null){
@@ -57,32 +58,30 @@ public class LoginReqHandler extends AbstractCmdHandler {
}
loginRespBody.clear();
ImPacket loginRespPacket = new ImPacket(Command.COMMAND_LOGIN_RESP, loginRespBody.toByte());
- ImAio.bSend(channelContext,loginRespPacket);
- ImAio.remove(channelContext, "loginName and token is incorrect");
+ Jim.bSend(imChannelContext, loginRespPacket);
+ Jim.remove(imChannelContext, "loginName and token is incorrect");
return null;
}
User user = loginRespBody.getUser();
- String userId = user.getId();
- IProtocol protocol = ImKit.protocol(null, channelContext);
+ IProtocol protocol = imServerChannelContext.getProtocolHandler().getProtocol();
String terminal = protocol == null ? "" : protocol.name();
user.setTerminal(terminal);
imSessionContext.getClient().setUser(user);
- ImAio.bindUser(channelContext,userId,imConfig.getMessageHelper().getBindListener());
+ Jim.bindUser(imServerChannelContext, user.getId());
//初始化绑定或者解绑群组;
- bindUnbindGroup(channelContext, user);
- loginServiceHandler.onSuccess(channelContext);
+ bindUnbindGroup(imChannelContext, user);
+ loginServiceHandler.onSuccess(imChannelContext);
loginRespBody.clear();
- ImPacket loginRespPacket = new ImPacket(Command.COMMAND_LOGIN_RESP, loginRespBody.toByte());
- return loginRespPacket;
+ return ProtocolManager.Converter.respPacket(loginRespBody, imChannelContext);
}
/**
* 初始化绑定或者解绑群组;
*/
- public void bindUnbindGroup(ChannelContext channelContext , User user)throws Exception{
+ public void bindUnbindGroup(ImChannelContext imChannelContext , User user)throws ImException{
String userId = user.getId();
List groups = user.getGroups();
if( groups != null){
- boolean isStore = ImConst.ON.equals(imConfig.getIsStore());
+ boolean isStore = ImConfig.Const.ON.equals(imConfig.getIsStore());
MessageHelper messageHelper = null;
List groupIds = null;
if(isStore){
@@ -97,14 +96,14 @@ public class LoginReqHandler extends AbstractCmdHandler {
ImPacket groupPacket = new ImPacket(Command.COMMAND_JOIN_GROUP_REQ,JsonKit.toJsonBytes(group));
try {
JoinGroupReqHandler joinGroupReqHandler = CommandManager.getCommand(Command.COMMAND_JOIN_GROUP_REQ, JoinGroupReqHandler.class);
- joinGroupReqHandler.bindGroup(groupPacket, channelContext);
+ joinGroupReqHandler.bindGroup(groupPacket, imChannelContext);
} catch (Exception e) {
log.error(e.toString(),e);
}
}
if(isStore && groupIds != null){
for(String groupId : groupIds){
- messageHelper.getBindListener().onAfterGroupUnbind(channelContext, groupId);
+ messageHelper.getBindListener().onAfterGroupUnbind(imChannelContext, groupId);
}
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/MessageReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/MessageReqHandler.java
index 5093579..65054c2 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/MessageReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/MessageReqHandler.java
@@ -1,10 +1,11 @@
package org.jim.server.command.handler;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConst;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
-import org.tio.core.ChannelContext;
+import org.jim.common.exception.ImException;
+import org.jim.server.config.ImServerConfig;
import org.jim.common.message.MessageHelper;
import org.jim.common.packets.Command;
import org.jim.common.packets.RespBody;
@@ -13,6 +14,7 @@ import org.jim.common.packets.MessageReqBody;
import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.command.AbstractCmdHandler;
+import org.jim.server.handler.ProtocolManager;
/**
* 获取聊天消息命令处理器
@@ -28,14 +30,14 @@ public class MessageReqHandler extends AbstractCmdHandler {
}
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
- RespBody resPacket = null;
- MessageReqBody messageReqBody = null;
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
+ RespBody resPacket;
+ MessageReqBody messageReqBody;
try{
messageReqBody = JsonKit.toBean(packet.getBody(),MessageReqBody.class);
}catch (Exception e) {
//用户消息格式不正确
- return getMessageFailedPacket(channelContext);
+ return getMessageFailedPacket(imChannelContext);
}
UserMessageData messageData = null;
MessageHelper messageHelper = imConfig.getMessageHelper();
@@ -56,8 +58,8 @@ public class MessageReqHandler extends AbstractCmdHandler {
//消息类型;
int type = messageReqBody.getType();
//如果用户ID为空或者type格式不正确,获取消息失败;
- if(StringUtils.isEmpty(userId) || (0 != type && 1 != type) || !ImConst.ON.equals(imConfig.getIsStore())){
- return getMessageFailedPacket(channelContext);
+ if(StringUtils.isEmpty(userId) || (0 != type && 1 != type) || !ImServerConfig.Const.ON.equals(imConfig.getIsStore())){
+ return getMessageFailedPacket(imChannelContext);
}
if(type == 0){
resPacket = new RespBody(Command.COMMAND_GET_MESSAGE_RESP,ImStatus.C10016);
@@ -78,7 +80,7 @@ public class MessageReqHandler extends AbstractCmdHandler {
if(0 == type){
messageData = messageHelper.getFriendsOfflineMessage(userId);
}else{
- return getMessageFailedPacket(channelContext);
+ return getMessageFailedPacket(imChannelContext);
}
}else{
//获取与指定用户离线消息;
@@ -90,15 +92,15 @@ public class MessageReqHandler extends AbstractCmdHandler {
}
}
resPacket.setData(messageData);
- return ImKit.ConvertRespPacket(resPacket, channelContext);
+ return ProtocolManager.Converter.respPacket(resPacket, imChannelContext);
}
/**
* 获取用户消息失败响应包;
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public ImPacket getMessageFailedPacket(ChannelContext channelContext){
+ public ImPacket getMessageFailedPacket(ImChannelContext imChannelContext) throws ImException{
RespBody resPacket = new RespBody(Command.COMMAND_GET_MESSAGE_RESP,ImStatus.C10015);
- return ImKit.ConvertRespPacket(resPacket, channelContext);
+ return ProtocolManager.Converter.respPacket(resPacket, imChannelContext);
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java b/jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java
index 58d363c..73152d4 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java
@@ -4,10 +4,9 @@
package org.jim.server.command.handler;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConst;
-import org.jim.common.ImAio;
-import org.jim.common.ImPacket;
-import org.jim.common.ImStatus;
+import org.jim.common.*;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImException;
import org.jim.common.message.MessageHelper;
import org.jim.common.packets.Command;
import org.jim.common.packets.Group;
@@ -17,7 +16,7 @@ import org.jim.common.packets.UserReqBody;
import org.jim.common.utils.ImKit;
import org.jim.common.utils.JsonKit;
import org.jim.server.command.AbstractCmdHandler;
-import org.tio.core.ChannelContext;
+import org.jim.server.handler.ProtocolManager;
import java.util.ArrayList;
import java.util.List;
@@ -34,14 +33,13 @@ public class UserReqHandler extends AbstractCmdHandler {
}
@Override
- public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handler(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
UserReqBody userReqBody = JsonKit.toBean(packet.getBody(),UserReqBody.class);
User user = null;
RespBody resPacket = null;
-
String userId = userReqBody.getUserid();
if(StringUtils.isEmpty(userId)) {
- return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_GET_USER_RESP, ImStatus.C10004), channelContext);
+ return ProtocolManager.Converter.respPacket(new RespBody(Command.COMMAND_GET_USER_RESP, ImStatus.C10004), imChannelContext);
}
//(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线]);
Integer type = userReqBody.getType() == null ? 2 : userReqBody.getType();
@@ -59,34 +57,34 @@ public class UserReqHandler extends AbstractCmdHandler {
}
}
if(user == null) {
- return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_GET_USER_RESP, ImStatus.C10004), channelContext);
+ return ProtocolManager.Converter.respPacket(new RespBody(Command.COMMAND_GET_USER_RESP, ImStatus.C10004), imChannelContext);
}
resPacket.setData(user);
- return ImKit.ConvertRespPacket(resPacket, channelContext);
+ return ProtocolManager.Converter.respPacket(resPacket, imChannelContext);
}
/**
* 根据用户id获取用户在线及离线用户;
- * @param userid
+ * @param userId
* @param type(0:所有在线用户,1:所有离线用户,2:所有用户[在线+离线])
* @return
*/
- public User getUserInfo(String userid , Integer type){
+ public User getUserInfo(String userId , Integer type){
User user = null;
//是否开启持久化;
- boolean isStore = ImConst.ON.equals(imConfig.getIsStore());
+ boolean isStore = ImConfig.Const.ON.equals(imConfig.getIsStore());
//消息持久化助手;
MessageHelper messageHelper = imConfig.getMessageHelper();
if(isStore){
- user = messageHelper.getUserByType(userid, 2);
+ user = messageHelper.getUserByType(userId, 2);
if(user == null) {
return null;
}
- user.setFriends(messageHelper.getAllFriendUsers(userid, type));
- user.setGroups(messageHelper.getAllGroupUsers(userid, type));
+ user.setFriends(messageHelper.getAllFriendUsers(userId, type));
+ user.setGroups(messageHelper.getAllGroupUsers(userId, type));
return user;
}else{
- user = ImAio.getUser(userid);
+ //user = Jim.getUser(userId);
if(user == null) {
return null;
}
@@ -129,14 +127,14 @@ public class UserReqHandler extends AbstractCmdHandler {
Group copyGroup = ImKit.copyGroupWithoutUsers(group);
List users = null;
if(flag == 1){
- users = ImAio.getAllUserByGroup(group.getGroup_id());
+ //users = Jim.getAllUserByGroup(group.getGroup_id());
}else if(flag == 0){
users = group.getUsers();
}
if(users != null && !users.isEmpty()){
List copyUsers = new ArrayList();
for(User userObj : users){
- User onlineUser = ImAio.getUser(userObj.getId());
+ /*User onlineUser = Jim.getUser(userObj.getId());
//在线
if(onlineUser != null && type == 0){
User copyOnlineUser = ImKit.copyUserWithoutFriendsGroups(onlineUser);
@@ -145,7 +143,7 @@ public class UserReqHandler extends AbstractCmdHandler {
}else if(onlineUser == null && type == 1){
User copyOnlineUser = ImKit.copyUserWithoutFriendsGroups(onlineUser);
copyUsers.add(copyOnlineUser);
- }
+ }*/
}
copyGroup.setUsers(copyUsers);
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/CmdProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/CmdProcessor.java
index b317a85..5975f92 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/CmdProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/CmdProcessor.java
@@ -3,24 +3,24 @@
*/
package org.jim.server.command.handler.processor;
-import org.tio.core.ChannelContext;
-
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
/**
* 不同协议CMD命令处理接口
* @author WChao
*
*/
-public interface CmdProcessor {
+public interface CmdProcessor extends ImConst {
/**
* 不同协议判断方法
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public boolean isProtocol(ChannelContext channelContext);
+ boolean isProtocol(ImChannelContext imChannelContext);
/**
* 该proCmd处理器名称(自定义)
* @return
*/
- public String name();
+ String name();
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/AsyncChatMessageProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/AsyncChatMessageProcessor.java
index 687438c..accb420 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/AsyncChatMessageProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/AsyncChatMessageProcessor.java
@@ -10,10 +10,9 @@
*/
package org.jim.server.command.handler.processor.chat;
+import org.jim.common.ImChannelContext;
import org.jim.common.packets.ChatBody;
import org.jim.server.command.handler.processor.CmdProcessor;
-import org.tio.core.ChannelContext;
-
/**
*
* 聊天消息异步业务处理器
@@ -26,8 +25,8 @@ public interface AsyncChatMessageProcessor extends CmdProcessor{
/**
* 聊天消息异步业务处理器执行方法;
* @param chatBody
- * @param channelContext
+ * @param imChannelContext
* @throws Exception
*/
- public void handler(ChatBody chatBody, ChannelContext channelContext);
+ void handler(ChatBody chatBody, ImChannelContext imChannelContext);
}
\ No newline at end of file
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/BaseAsyncChatMessageProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/BaseAsyncChatMessageProcessor.java
index 99c1540..c131f0e 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/BaseAsyncChatMessageProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/BaseAsyncChatMessageProcessor.java
@@ -1,14 +1,13 @@
package org.jim.server.command.handler.processor.chat;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
+import org.jim.common.config.ImConfig;
import org.jim.common.message.MessageHelper;
import org.jim.common.packets.ChatBody;
import org.jim.common.packets.ChatType;
import org.jim.common.utils.ChatKit;
-import org.jim.server.command.CommandManager;
-import org.tio.core.ChannelContext;
-
+import org.jim.server.config.ImServerConfig;
import java.util.List;
/**
* @author WChao
@@ -16,16 +15,16 @@ import java.util.List;
*/
public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageProcessor,ImConst {
- protected ImConfig imConfig = null;
+ protected ImServerConfig imServerConfig = ImConfig.Global.get();
/**
* 供子类拿到消息进行业务处理(如:消息持久化到数据库等)的抽象方法
* @param chatBody
- * @param channelContext
+ * @param imChannelContext
*/
- protected abstract void doHandler(ChatBody chatBody, ChannelContext channelContext);
+ protected abstract void doHandler(ChatBody chatBody, ImChannelContext imChannelContext);
@Override
- public boolean isProtocol(ChannelContext channelContext) {
+ public boolean isProtocol(ImChannelContext imChannelContext) {
return true;
}
@@ -35,12 +34,9 @@ public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageP
}
@Override
- public void handler(ChatBody chatBody, ChannelContext channelContext){
- if(imConfig == null) {
- imConfig = CommandManager.getImConfig();
- }
+ public void handler(ChatBody chatBody, ImChannelContext imChannelContext){
//开启持久化
- if(ON.equals(imConfig.getIsStore())){
+ if(ImServerConfig.Const.ON.equals(imServerConfig.getIsStore())){
//存储群聊消息;
if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == chatBody.getChatType()){
pushGroupMessages(PUSH,STORE, chatBody);
@@ -49,13 +45,13 @@ public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageP
String to = chatBody.getTo();
String sessionId = ChatKit.sessionId(from,to);
writeMessage(STORE,USER+":"+sessionId,chatBody);
- boolean isOnline = ChatKit.isOnline(to,imConfig);
+ boolean isOnline = ChatKit.isOnline(to,imServerConfig);
if(!isOnline){
writeMessage(PUSH,USER+":"+to+":"+from,chatBody);
}
}
}
- doHandler(chatBody, channelContext);
+ doHandler(chatBody, imChannelContext);
}
/**
* 推送持久化群组消息
@@ -64,7 +60,7 @@ public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageP
* @param chatBody
*/
private void pushGroupMessages(String pushTable, String storeTable , ChatBody chatBody){
- MessageHelper messageHelper = imConfig.getMessageHelper();
+ MessageHelper messageHelper = imServerConfig.getMessageHelper();
String group_id = chatBody.getGroup_id();
//先将群消息持久化到存储Timeline;
writeMessage(storeTable,GROUP+":"+group_id,chatBody);
@@ -72,10 +68,10 @@ public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageP
//通过写扩散模式将群消息同步到所有的群成员
for(String userId : userIds){
boolean isOnline = false;
- if(ON.equals(imConfig.getIsStore()) && ON.equals(imConfig.getIsCluster())){
+ if(ImServerConfig.Const.ON.equals(imServerConfig.getIsStore()) && ImServerConfig.Const.ON.equals(imServerConfig.getIsCluster())){
isOnline = messageHelper.isOnline(userId);
}else{
- isOnline = ChatKit.isOnline(userId,imConfig);
+ isOnline = ChatKit.isOnline(userId,imServerConfig);
}
if(!isOnline){
writeMessage(pushTable, GROUP+":"+group_id+":"+userId, chatBody);
@@ -84,7 +80,7 @@ public abstract class BaseAsyncChatMessageProcessor implements AsyncChatMessageP
}
private void writeMessage(String timelineTable , String timelineId , ChatBody chatBody){
- MessageHelper messageHelper = imConfig.getMessageHelper();
+ MessageHelper messageHelper = imServerConfig.getMessageHelper();
messageHelper.writeMessage(timelineTable, timelineId, chatBody);
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/ChatCmdProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/ChatCmdProcessor.java
index fad9a61..3696810 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/ChatCmdProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/ChatCmdProcessor.java
@@ -1,5 +1,6 @@
package org.jim.server.command.handler.processor.chat;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
import org.tio.core.ChannelContext;
import org.jim.server.command.handler.processor.CmdProcessor;
@@ -12,8 +13,8 @@ public interface ChatCmdProcessor extends CmdProcessor {
/**
* 聊天cmd业务处理器处理方法;
* @param chatPacket
- * @param channelContext
+ * @param imChannelContext
* @throws Exception
*/
- public void handler(ImPacket chatPacket,ChannelContext channelContext);
+ void handler(ImPacket chatPacket, ImChannelContext imChannelContext);
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/DefaultAsyncChatMessageProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/DefaultAsyncChatMessageProcessor.java
index 1701211..15cf95a 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/DefaultAsyncChatMessageProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/DefaultAsyncChatMessageProcessor.java
@@ -1,7 +1,7 @@
package org.jim.server.command.handler.processor.chat;
+import org.jim.common.ImChannelContext;
import org.jim.common.packets.ChatBody;
-import org.tio.core.ChannelContext;
/**
* @author WChao
* @date 2018年4月3日 下午1:12:30
@@ -9,7 +9,7 @@ import org.tio.core.ChannelContext;
public class DefaultAsyncChatMessageProcessor extends BaseAsyncChatMessageProcessor {
@Override
- public void doHandler(ChatBody chatBody, ChannelContext channelContext){
+ public void doHandler(ChatBody chatBody, ImChannelContext imChannelContext){
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/MsgQueueRunnable.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/MsgQueueRunnable.java
index 41ee4ed..b43e630 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/MsgQueueRunnable.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/chat/MsgQueueRunnable.java
@@ -1,5 +1,6 @@
package org.jim.server.command.handler.processor.chat;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
import org.jim.common.ImPacket;
import org.jim.common.packets.ChatBody;
@@ -10,6 +11,8 @@ import org.jim.server.command.handler.ChatReqHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
+import org.tio.utils.queue.FullWaitQueue;
+import org.tio.utils.queue.TioFullWaitQueue;
import org.tio.utils.thread.pool.AbstractQueueRunnable;
import java.util.concurrent.Executor;
@@ -22,38 +25,30 @@ public class MsgQueueRunnable extends AbstractQueueRunnable {
private Logger log = LoggerFactory.getLogger(MsgQueueRunnable.class);
- private ChannelContext channelContext = null;
+ private ImChannelContext imChannelContext;
private AsyncChatMessageProcessor chatMessageProcessor;
@Override
- public boolean addMsg(ImPacket msg) {
- if (this.isCanceled()) {
- log.error("{}, 任务已经取消,{}添加到消息队列失败", channelContext, msg);
- return false;
- }
- return msgQueue.add(msg);
+ public FullWaitQueue getMsgQueue() {
+ return new TioFullWaitQueue(Integer.MAX_VALUE,true);
}
- public MsgQueueRunnable(ChannelContext channelContext, Executor executor) {
+ public MsgQueueRunnable(ImChannelContext imChannelContext, Executor executor) {
super(executor);
- this.channelContext = channelContext;
+ this.imChannelContext = imChannelContext;
ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ,ChatReqHandler.class);
chatMessageProcessor = chatReqHandler.getProcessor(ImConst.BASE_ASYNC_CHAT_MESSAGE_PROCESSOR,BaseAsyncChatMessageProcessor.class).get(0);
}
@Override
public void runTask() {
- int queueSize = msgQueue.size();
- if (queueSize == 0) {
- return;
- }
ImPacket packet = null;
- while ((packet = msgQueue.poll()) != null) {
+ while ((packet = this.getMsgQueue().poll()) != null) {
if(chatMessageProcessor != null){
try {
- ChatBody chatBody = ChatKit.toChatBody(packet.getBody(), channelContext);
- chatMessageProcessor.handler(chatBody, channelContext);
+ ChatBody chatBody = ChatKit.toChatBody(packet.getBody(), imChannelContext);
+ chatMessageProcessor.handler(chatBody, imChannelContext);
} catch (Exception e) {
log.error(e.toString(),e);
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/group/GroupCmdProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/group/GroupCmdProcessor.java
index 7edf2cc..2087442 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/group/GroupCmdProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/group/GroupCmdProcessor.java
@@ -1,10 +1,9 @@
package org.jim.server.command.handler.processor.group;
+import org.jim.common.ImChannelContext;
import org.jim.common.packets.Group;
import org.jim.common.packets.JoinGroupRespBody;
import org.jim.server.command.handler.processor.CmdProcessor;
-import org.tio.core.ChannelContext;
-
/**
* @author ensheng
*/
@@ -12,8 +11,8 @@ public interface GroupCmdProcessor extends CmdProcessor {
/**
* 加入群组处理
* @param joinGroup
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- JoinGroupRespBody join(Group joinGroup, ChannelContext channelContext);
+ JoinGroupRespBody join(Group joinGroup, ImChannelContext imChannelContext);
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/HandshakeCmdProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/HandshakeCmdProcessor.java
index 0ae4061..2f649dd 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/HandshakeCmdProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/HandshakeCmdProcessor.java
@@ -3,8 +3,9 @@
*/
package org.jim.server.command.handler.processor.handshake;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.tio.core.ChannelContext;
+import org.jim.common.exception.ImException;
import org.jim.server.command.handler.processor.CmdProcessor;
/**
* @ClassName HandshakeCmdProcessor
@@ -17,18 +18,18 @@ public interface HandshakeCmdProcessor extends CmdProcessor {
/**
* 对httpResponsePacket参数进行补充并返回,如果返回null表示不想和对方建立连接,框架会断开连接,如果返回非null,框架会把这个对象发送给对方
* @param packet
- * @param channelContext
+ * @param imChannelContext
* @return
- * @throws Exception
+ * @throws ImException
* @author: Wchao
*/
- public ImPacket handshake(ImPacket packet,ChannelContext channelContext) throws Exception;
+ ImPacket handshake(ImPacket packet, ImChannelContext imChannelContext) throws ImException;
/**
* 握手成功后
* @param packet
- * @param channelContext
- * @throws Exception
+ * @param imChannelContext
+ * @throws ImException
* @author Wchao
*/
- public void onAfterHandshaked(ImPacket packet, ChannelContext channelContext) throws Exception;
+ void onAfterHandshake(ImPacket packet, ImChannelContext imChannelContext) throws ImException;
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/TcpHandshakeProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/TcpHandshakeProcessor.java
index 5fa8c29..352418f 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/TcpHandshakeProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/TcpHandshakeProcessor.java
@@ -3,14 +3,16 @@
*/
package org.jim.server.command.handler.processor.handshake;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.jim.common.Protocol;
-import org.tio.core.ChannelContext;
+import org.jim.common.ImSessionContext;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.Command;
import org.jim.common.packets.HandshakeBody;
import org.jim.common.packets.RespBody;
import org.jim.common.tcp.TcpSessionContext;
-import org.jim.common.utils.ImKit;
+import org.jim.server.handler.ProtocolManager;
+
/**
* 版本: [1.0]
* 功能说明:
@@ -19,9 +21,9 @@ import org.jim.common.utils.ImKit;
public class TcpHandshakeProcessor implements HandshakeCmdProcessor {
@Override
- public ImPacket handshake(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handshake(ImPacket packet, ImChannelContext channelContext) throws ImException {
RespBody handshakeBody = new RespBody(Command.COMMAND_HANDSHAKE_RESP,new HandshakeBody(Protocol.HANDSHAKE_BYTE));
- ImPacket handshakePacket = ImKit.ConvertRespPacket(handshakeBody,channelContext);
+ ImPacket handshakePacket = ProtocolManager.Converter.respPacket(handshakeBody,channelContext);
return handshakePacket;
}
@@ -29,16 +31,16 @@ public class TcpHandshakeProcessor implements HandshakeCmdProcessor {
* 握手成功后
* @param packet
* @param channelContext
- * @throws Exception
+ * @throws ImException
* @author Wchao
*/
@Override
- public void onAfterHandshaked(ImPacket packet, ChannelContext channelContext)throws Exception {
+ public void onAfterHandshake(ImPacket packet, ImChannelContext channelContext)throws ImException {
}
@Override
- public boolean isProtocol(ChannelContext channelContext){
- Object sessionContext = channelContext.getAttribute();
+ public boolean isProtocol(ImChannelContext channelContext){
+ ImSessionContext sessionContext = channelContext.getSessionContext();
if(sessionContext == null){
return false;
}else if(sessionContext instanceof TcpSessionContext){
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/WsHandshakeProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/WsHandshakeProcessor.java
index 449eb97..c76dafe 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/WsHandshakeProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/handshake/WsHandshakeProcessor.java
@@ -3,9 +3,10 @@
*/
package org.jim.server.command.handler.processor.handshake;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImPacket;
-import org.jim.common.Protocol;
-import org.tio.core.ChannelContext;
+import org.jim.common.ImSessionContext;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.Command;
import org.jim.common.ws.WsRequestPacket;
import org.jim.common.ws.WsResponsePacket;
@@ -20,15 +21,15 @@ public class WsHandshakeProcessor implements HandshakeCmdProcessor {
/**
* 对httpResponsePacket参数进行补充并返回,如果返回null表示不想和对方建立连接,框架会断开连接,如果返回非null,框架会把这个对象发送给对方
* @param packet
- * @param channelContext
+ * @param imChannelContext
* @return
* @throws Exception
* @author: WChao
*/
@Override
- public ImPacket handshake(ImPacket packet, ChannelContext channelContext) throws Exception {
+ public ImPacket handshake(ImPacket packet, ImChannelContext imChannelContext) throws ImException {
WsRequestPacket wsRequestPacket = (WsRequestPacket) packet;
- WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getAttribute();
+ WsSessionContext wsSessionContext = (WsSessionContext) imChannelContext.getSessionContext();
if (wsRequestPacket.isHandShake()) {
WsResponsePacket wsResponsePacket = new WsResponsePacket();
wsResponsePacket.setHandShake(true);
@@ -42,24 +43,24 @@ public class WsHandshakeProcessor implements HandshakeCmdProcessor {
/**
* 握手成功后
* @param packet
- * @param channelContext
+ * @param imChannelContext
* @throws Exception
* @author Wchao
*/
@Override
- public void onAfterHandshaked(ImPacket packet, ChannelContext channelContext)throws Exception {
+ public void onAfterHandshake(ImPacket packet, ImChannelContext imChannelContext)throws ImException {
}
/**
* @Author WChao
* @Description 判断当前连接是否属于WS协议
- * @param [channelContext]
+ * @param imChannelContext
* @return boolean
**/
@Override
- public boolean isProtocol(ChannelContext channelContext){
- Object sessionContext = channelContext.getAttribute();
+ public boolean isProtocol(ImChannelContext imChannelContext){
+ ImSessionContext sessionContext = imChannelContext.getSessionContext();
if(sessionContext == null){
return false;
}else if(sessionContext instanceof WsSessionContext){
@@ -71,13 +72,13 @@ public class WsHandshakeProcessor implements HandshakeCmdProcessor {
/**
* @Author WChao
* @Description 协议名称
- * @param []
+ * @param
* @return java.lang.String
**/
@Override
public String name() {
- return Protocol.WEBSOCKET;
+ return Protocol.WEB_SOCKET;
}
}
diff --git a/jim-server/src/main/java/org/jim/server/command/handler/processor/login/LoginCmdProcessor.java b/jim-server/src/main/java/org/jim/server/command/handler/processor/login/LoginCmdProcessor.java
index 1016768..5bc8ce1 100644
--- a/jim-server/src/main/java/org/jim/server/command/handler/processor/login/LoginCmdProcessor.java
+++ b/jim-server/src/main/java/org/jim/server/command/handler/processor/login/LoginCmdProcessor.java
@@ -3,7 +3,7 @@
*/
package org.jim.server.command.handler.processor.login;
-import org.tio.core.ChannelContext;
+import org.jim.common.ImChannelContext;
import org.jim.common.packets.LoginReqBody;
import org.jim.common.packets.LoginRespBody;
import org.jim.server.command.handler.processor.CmdProcessor;
@@ -15,14 +15,14 @@ public interface LoginCmdProcessor extends CmdProcessor {
/**
* 执行登录操作接口方法
* @param loginReqBody
- * @param channelContext
+ * @param imChannelContext
* @return
*/
- public LoginRespBody doLogin(LoginReqBody loginReqBody ,ChannelContext channelContext);
+ LoginRespBody doLogin(LoginReqBody loginReqBody , ImChannelContext imChannelContext);
/**
* 登录成功回调方法
- * @param channelContext
+ * @param imChannelContext
*/
- public void onSuccess(ChannelContext channelContext);
+ void onSuccess(ImChannelContext imChannelContext);
}
diff --git a/jim-server/src/main/java/org/jim/server/config/DefaultImConfigBuilder.java b/jim-server/src/main/java/org/jim/server/config/DefaultImConfigBuilder.java
new file mode 100644
index 0000000..3d0d93d
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/config/DefaultImConfigBuilder.java
@@ -0,0 +1,32 @@
+/**
+ *
+ */
+package org.jim.server.config;
+
+import org.jim.common.http.HttpConfig;
+import org.jim.common.ws.WsConfig;
+
+/**
+ * @author WChao
+ *
+ */
+public class DefaultImConfigBuilder extends ImServerConfigBuilder {
+
+ @Override
+ public ImServerConfigBuilder configHttp(HttpConfig httpConfig) {
+ // TODO Auto-generated method stub
+ return this;
+ }
+
+ @Override
+ public ImServerConfigBuilder configWs(WsConfig wsServerConfig) {
+ // TODO Auto-generated method stub
+ return this;
+ }
+
+ @Override
+ protected ImServerConfigBuilder getThis() {
+ return this;
+ }
+
+}
diff --git a/jim-server/src/main/java/org/jim/server/config/ImServerConfig.java b/jim-server/src/main/java/org/jim/server/config/ImServerConfig.java
new file mode 100644
index 0000000..ad3f066
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/config/ImServerConfig.java
@@ -0,0 +1,279 @@
+package org.jim.server.config;
+
+import org.jim.common.ImHandler;
+import org.jim.common.config.ImConfig;
+import org.jim.common.cluster.ImCluster;
+import org.jim.common.http.HttpConfig;
+import org.jim.common.listener.ImListener;
+import org.jim.common.message.MessageHelper;
+import org.jim.common.ws.WsConfig;
+import org.jim.server.handler.DefaultImServerHandler;
+import org.jim.server.handler.ImServerHandler;
+import org.jim.server.handler.ImServerHandlerAdapter;
+import org.jim.server.listener.DefaultImServerListener;
+import org.jim.server.listener.ImServerListener;
+import org.jim.server.listener.ImServerListenerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tio.core.ssl.SslConfig;
+import org.tio.server.ServerTioConfig;
+
+import java.util.Objects;
+
+/**
+ * @ClassName ImServerConfig
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/4 10:40
+ * @Version 1.0
+ **/
+public class ImServerConfig extends ImConfig {
+
+ private static Logger log = LoggerFactory.getLogger(ImServerConfig.class);
+ /**
+ * 服务端消息处理器
+ */
+ private ImServerHandler imServerHandler;
+ /**
+ * 服务端消息监听器
+ */
+ private ImServerListener imServerListener;
+
+ /**
+ * 用户消息持久化助手;
+ */
+ private MessageHelper messageHelper;
+ /**
+ * 是否开启持久化;
+ */
+ private String isStore = Const.OFF;
+ /**
+ * 是否开启集群;
+ */
+ private String isCluster = Const.OFF;
+ /**
+ * 是否开启SSL加密
+ */
+ private String isSSL = Const.OFF;
+ /**
+ * SSL配置
+ */
+ private SslConfig sslConfig;
+ /**
+ * 集群配置
+ * 如果此值不为null,就表示要集群
+ */
+ private ImCluster cluster;
+
+ /**
+ * http相关配置;
+ */
+ private HttpConfig httpConfig;
+ /**
+ * WebSocket相关配置;
+ */
+ private WsConfig wsConfig;
+
+ private ImServerConfig(ImServerHandler imServerHandler, ImServerListener imServerListener){
+ setImServerHandler(imServerHandler);
+ setImServerListener(imServerListener);
+ this.tioConfig = new ServerTioConfig(this.getName(), new ImServerHandlerAdapter(this.imServerHandler),new ImServerListenerAdapter(this.imServerListener));
+ }
+
+ public static Builder newBuilder(){
+ return new ImServerConfig.Builder();
+ }
+
+ @Override
+ public ImHandler getImHandler() {
+ return getImServerHandler();
+ }
+
+ @Override
+ public ImListener getImListener() {
+ return getImServerListener();
+ }
+
+ public static class Builder extends ImConfig.Builder{
+
+ private ImServerListener imServerListener;
+
+ private MessageHelper messageHelper;
+
+ private String isStore = Const.OFF;
+
+ private String isCluster = Const.OFF;
+
+ private String isSSL = Const.OFF;
+
+ private SslConfig sslConfig;
+
+ private ImCluster cluster;
+
+ private HttpConfig httpConfig;
+
+ private WsConfig wsConfig;
+
+ @Override
+ protected Builder getThis() {
+ return this;
+ }
+
+ public Builder serverListener(ImServerListener imServerListener){
+ this.imServerListener = imServerListener;
+ return getThis();
+ }
+
+ public Builder messageHelper(MessageHelper messageHelper){
+ this.messageHelper = messageHelper;
+ return getThis();
+ }
+
+ public Builder isStore(String isStore){
+ this.isStore = isStore;
+ return getThis();
+ }
+
+ public Builder isCluster(String isCluster){
+ this.isCluster = isCluster;
+ return getThis();
+ }
+
+ public Builder isSSL(String isSSL){
+ this.isSSL = isSSL;
+ return getThis();
+ }
+
+ public Builder sslConfig(SslConfig sslConfig){
+ this.sslConfig = sslConfig;
+ return getThis();
+ }
+
+ public Builder cluster(ImCluster cluster){
+ this.cluster = cluster;
+ return getThis();
+ }
+
+ public Builder httConfig(HttpConfig httpConfig){
+ this.httpConfig = httpConfig;
+ return getThis();
+ }
+
+ public Builder wsConfig(WsConfig wsConfig){
+ this.wsConfig = wsConfig;
+ return getThis();
+ }
+
+ @Override
+ public ImServerConfig build(){
+ ImServerConfig imServerConfig = new ImServerConfig(new DefaultImServerHandler(), this.imServerListener);
+ imServerConfig.setBindIp(this.bindIp);
+ imServerConfig.setBindPort(this.bindPort);
+ imServerConfig.setReadBufferSize(this.readBufferSize);
+ imServerConfig.setMessageHelper(this.messageHelper);
+ imServerConfig.setIsStore(this.isStore);
+ imServerConfig.setIsCluster(this.isCluster);
+ imServerConfig.setIsSSL(this.isSSL);
+ imServerConfig.setSslConfig(this.sslConfig);
+ imServerConfig.setCluster(this.cluster);
+ imServerConfig.setHttpConfig(this.httpConfig);
+ imServerConfig.setWsConfig(this.wsConfig);
+ imServerConfig.setHeartbeatTimeout(this.heartbeatTimeout);
+ imServerConfig.setImGroupListener(this.imGroupListener);
+ imServerConfig.setImUserListener(this.imUserListener);
+ return imServerConfig;
+ }
+ }
+
+ public ImServerListener getImServerListener() {
+ return imServerListener;
+ }
+
+ public void setImServerHandler(ImServerHandler imServerHandler) {
+ this.imServerHandler = imServerHandler;
+ if(Objects.isNull(this.imServerHandler)){
+ this.imServerHandler = new DefaultImServerHandler();
+ }
+ }
+
+ public void setImServerListener(ImServerListener imServerListener) {
+ this.imServerListener = imServerListener;
+ if(Objects.isNull(this.imServerListener)){
+ this.imServerListener = new DefaultImServerListener();
+ }
+ }
+
+ public MessageHelper getMessageHelper() {
+ return messageHelper;
+ }
+
+ public void setMessageHelper(MessageHelper messageHelper) {
+ this.messageHelper = messageHelper;
+ }
+
+ public String getIsStore() {
+ return isStore;
+ }
+
+ public void setIsStore(String isStore) {
+ this.isStore = isStore;
+ }
+
+ public String getIsCluster() {
+ return isCluster;
+ }
+
+ /**
+ * 设置是否开启集群
+ * @param isCluster
+ */
+ public void setIsCluster(String isCluster) {
+ this.isCluster = isCluster;
+ }
+
+ public String getIsSSL() {
+ return isSSL;
+ }
+
+ public void setIsSSL(String isSSL) {
+ this.isSSL = isSSL;
+ }
+
+ public SslConfig getSslConfig() {
+ return sslConfig;
+ }
+
+ public void setSslConfig(SslConfig sslConfig) {
+ this.sslConfig = sslConfig;
+ this.tioConfig.setSslConfig(sslConfig);
+ }
+
+ public ImCluster getCluster() {
+ return cluster;
+ }
+
+ public void setCluster(ImCluster cluster) {
+ this.cluster = cluster;
+
+ }
+
+ public HttpConfig getHttpConfig() {
+ return httpConfig;
+ }
+
+ public void setHttpConfig(HttpConfig httpConfig) {
+ this.httpConfig = httpConfig;
+ }
+
+ public WsConfig getWsConfig() {
+ return wsConfig;
+ }
+
+ public void setWsConfig(WsConfig wsConfig) {
+ this.wsConfig = wsConfig;
+ }
+
+ public ImServerHandler getImServerHandler() {
+ return imServerHandler;
+ }
+}
diff --git a/jim-server/src/main/java/org/jim/server/config/ImServerConfigBuilder.java b/jim-server/src/main/java/org/jim/server/config/ImServerConfigBuilder.java
new file mode 100644
index 0000000..96fd33e
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/config/ImServerConfigBuilder.java
@@ -0,0 +1,57 @@
+/**
+ *
+ */
+package org.jim.server.config;
+
+import org.jim.common.http.HttpConfig;
+import org.jim.common.ws.WsConfig;
+import org.jim.server.listener.ImServerListener;
+
+/**
+ * @author WChao
+ * 2018/08/26
+ */
+public abstract class ImServerConfigBuilder{
+
+ protected T conf;
+ protected ImServerListener serverListener;
+ protected HttpConfig httpConfig;
+ protected WsConfig wsConfig;
+
+ /**
+ * 留给子类配置Http服务器相关配置
+ * @param httpConfig
+ * @throws Exception
+ * @return
+ */
+ public abstract B configHttp(HttpConfig httpConfig)throws Exception;
+
+ /**
+ * 配置WebSocket服务器相关配置
+ * @param wsConfig
+ * @throws Exception
+ * @return
+ *
+ */
+ public abstract B configWs(WsConfig wsConfig)throws Exception;
+
+ /**
+ * 供子类获取自身builder抽象类;
+ * @return
+ */
+ protected abstract B getThis();
+
+ public B serverListener(ImServerListener serverListener){
+ this.serverListener = serverListener;
+ return getThis();
+ }
+
+ public T build() throws Exception{
+ this.httpConfig = HttpConfig.newBuilder().build();
+ this.wsConfig = WsConfig.newBuilder().build();
+ this.configHttp(httpConfig);
+ this.configWs(wsConfig);
+ return conf;
+ }
+
+}
diff --git a/jim-server/src/main/java/org/jim/server/config/PropertyImServerConfigBuilder.java b/jim-server/src/main/java/org/jim/server/config/PropertyImServerConfigBuilder.java
new file mode 100644
index 0000000..59e64c6
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/config/PropertyImServerConfigBuilder.java
@@ -0,0 +1,56 @@
+/**
+ *
+ */
+package org.jim.server.config;
+
+import org.jim.common.http.HttpConfig;
+import org.jim.common.utils.PropUtil;
+import org.jim.common.ws.WsConfig;
+
+/**
+ * @author WChao
+ * 2018/08/26
+ */
+public class PropertyImServerConfigBuilder extends ImServerConfigBuilder {
+
+ public PropertyImServerConfigBuilder(String file) {
+ PropUtil.use(file);
+ }
+
+ @Override
+ public PropertyImServerConfigBuilder configHttp(HttpConfig httpConfig)throws Exception{
+ httpConfig.setBindPort(PropUtil.getInt("jim.port"));
+ //设置web访问路径;html/css/js等的根目录,支持classpath:,也支持绝对路径
+ httpConfig.setPageRoot(PropUtil.get("jim.http.page"));
+ //不缓存资源;
+ httpConfig.setMaxLiveTimeOfStaticRes(PropUtil.getInt("jim.http.max.live.time"));
+ //设置j-im mvc扫描目录;
+ httpConfig.setScanPackages(PropUtil.get("jim.http.scan.packages").split(","));
+ return this;
+ }
+
+ @Override
+ public PropertyImServerConfigBuilder configWs(WsConfig wsConfig)throws Exception{
+
+ return this;
+ }
+
+ @Override
+ protected PropertyImServerConfigBuilder getThis() {
+ return this;
+ }
+
+ @Override
+ public ImServerConfig build()throws Exception {
+ super.build();
+ return ImServerConfig.newBuilder()
+ .bindIp(PropUtil.get("jim.bind.ip"))
+ .bindPort(PropUtil.getInt("jim.port"))
+ .heartbeatTimeout(PropUtil.getLong("jim.heartbeat.timeout"))
+ .isStore(PropUtil.get("jim.store"))
+ .httConfig(this.httpConfig)
+ .wsConfig(this.wsConfig)
+ .serverListener(this.serverListener)
+ .isCluster(PropUtil.get("jim.cluster")).build();
+ }
+}
diff --git a/jim-server/src/main/java/org/jim/server/handler/AbstractProtocolHandler.java b/jim-server/src/main/java/org/jim/server/handler/AbstractProtocolHandler.java
index 0d1d65b..ad3dedf 100644
--- a/jim-server/src/main/java/org/jim/server/handler/AbstractProtocolHandler.java
+++ b/jim-server/src/main/java/org/jim/server/handler/AbstractProtocolHandler.java
@@ -3,54 +3,31 @@
*/
package org.jim.server.handler;
-import org.jim.common.ImConfig;
-import org.jim.common.protocol.IProtocol;
-import org.tio.core.ChannelContext;
-import org.tio.core.exception.AioDecodeException;
-import org.tio.core.intf.Packet;
-import org.tio.server.intf.ServerAioHandler;
-
-import java.nio.ByteBuffer;
+import org.jim.common.exception.ImException;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.server.config.ImServerConfig;
/**
- * 版本: [1.0] 功能说明: 封装tioServerAioHandler,提供更丰富的方法供客户端定制化;
+ * 版本: [1.0] 功能说明: 抽象协议处理器;
* @author : WChao 创建时间: 2017年8月3日 上午9:47:44
*/
-public abstract class AbstractProtocolHandler implements ServerAioHandler{
- /**
- * 获取不同协议管理器
- * @return
- */
- public abstract IProtocol protocol();
+public abstract class AbstractProtocolHandler implements ImServerHandler {
+
+ protected AbstractProtocol protocol;
+
+ public AbstractProtocolHandler(){};
+
+ public AbstractProtocolHandler(AbstractProtocol protocol){
+ this.protocol = protocol;
+ }
/**
* 初始化不同协议
- * @param imConfig
- * @throws Exception
+ * @param imServerConfig
+ * @throws ImException
*/
- public abstract void init(ImConfig imConfig)throws Exception;
+ public abstract void init(ImServerConfig imServerConfig)throws ImException;
- /**
- * 将数据解码为消息Packet包
- * @param buffer
- * @param channelContext
- * @return
- * @throws AioDecodeException
- */
- public abstract Packet decode(ByteBuffer buffer, ChannelContext channelContext)throws AioDecodeException;
-
- /**
- * t-io解码适配方法
- * @param buffer
- * @param limit
- * @param position
- * @param readableLength
- * @param channelContext
- * @return
- * @throws AioDecodeException
- */
- @Override
- public Packet decode(ByteBuffer buffer, int limit, int position,int readableLength, ChannelContext channelContext)throws AioDecodeException {
- return decode(buffer,channelContext);
+ public AbstractProtocol getProtocol() {
+ return protocol;
}
-
}
diff --git a/jim-server/src/main/java/org/jim/server/handler/DefaultImServerHandler.java b/jim-server/src/main/java/org/jim/server/handler/DefaultImServerHandler.java
new file mode 100644
index 0000000..0c1bb12
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/handler/DefaultImServerHandler.java
@@ -0,0 +1,79 @@
+package org.jim.server.handler;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImPacket;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.common.exception.ImException;
+import org.jim.server.ImServerChannelContext;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * @ClassName DefaultImServerHandler
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/6 2:25
+ * @Version 1.0
+ **/
+public class DefaultImServerHandler implements ImServerHandler{
+ /**
+ * 处理消息包
+ * @param imPacket
+ * @param imChannelContext
+ * @throws Exception
+ */
+ @Override
+ public void handler(ImPacket imPacket, ImChannelContext imChannelContext) throws ImException {
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)imChannelContext;
+ AbstractProtocolHandler handler = imServerChannelContext.getProtocolHandler();
+ if(Objects.isNull(handler)){
+ return;
+ }
+ handler.handler(imPacket, imChannelContext);
+ }
+
+ /**
+ * 编码
+ * @param imPacket
+ * @param imConfig
+ * @param imChannelContext
+ * @return
+ */
+ @Override
+ public ByteBuffer encode(ImPacket imPacket, ImConfig imConfig, ImChannelContext imChannelContext) {
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)imChannelContext;
+ AbstractProtocolHandler handler = imServerChannelContext.getProtocolHandler();
+ if(handler != null){
+ return handler.encode(imPacket, imConfig, imServerChannelContext);
+ }
+ return null;
+ }
+
+ /**
+ * 解码
+ * @param buffer
+ * @param limit
+ * @param position
+ * @param readableLength
+ * @param imChannelContext
+ * @return
+ * @throws ImDecodeException
+ */
+ @Override
+ public ImPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ImChannelContext imChannelContext) throws ImDecodeException {
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)imChannelContext;
+ AbstractProtocolHandler handler;
+ if(Objects.isNull(imServerChannelContext.getSessionContext())){
+ handler = ProtocolManager.initProtocolHandler(buffer, imServerChannelContext);
+ }else{
+ handler = imServerChannelContext.getProtocolHandler();
+ }
+ if(handler != null){
+ return handler.decode(buffer, limit, position, readableLength, imServerChannelContext);
+ }else{
+ throw new ImDecodeException("不支持的协议类型,无法找到对应的协议解码器!");
+ }
+ }
+}
diff --git a/jim-server/src/main/java/org/jim/server/handler/IProtocolHandler.java b/jim-server/src/main/java/org/jim/server/handler/IProtocolHandler.java
new file mode 100644
index 0000000..bdd7a60
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/handler/IProtocolHandler.java
@@ -0,0 +1,11 @@
+package org.jim.server.handler;
+
+/**
+ * @ClassName ProtocolHandler
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/11 14:07
+ * @Version 1.0
+ **/
+public interface IProtocolHandler extends ImServerHandler{
+}
diff --git a/jim-server/src/main/java/org/jim/server/handler/ImServerAioHandler.java b/jim-server/src/main/java/org/jim/server/handler/ImServerAioHandler.java
deleted file mode 100644
index 397e7cf..0000000
--- a/jim-server/src/main/java/org/jim/server/handler/ImServerAioHandler.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.jim.server.handler;
-
-import java.nio.ByteBuffer;
-
-import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
-import org.jim.common.ImSessionContext;
-import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-import org.tio.core.exception.AioDecodeException;
-import org.tio.core.intf.Packet;
-import org.jim.server.ImServerGroupContext;
-import org.jim.server.command.handler.processor.chat.MsgQueueRunnable;
-import org.tio.server.intf.ServerAioHandler;
-/**
- *
- * @author WChao
- *
- */
-public class ImServerAioHandler implements ServerAioHandler {
-
- private ImConfig imConfig;
-
- public ImServerAioHandler(ImConfig imConfig) {
- this.imConfig = imConfig;
- }
- /**
- * @see org.tio.core.intf.AioHandler#handler(org.tio.core.intf.Packet)
- *
- * @param packet
- * @return
- * @throws Exception
- * @author: Wchao
- * 2016年11月18日 上午9:37:44
- *
- */
- @Override
- public void handler(Packet packet, ChannelContext channelContext) throws Exception {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- AbstractProtocolHandler handler = (AbstractProtocolHandler)imSessionContext.getProtocolHandler();
- if(handler != null){
- handler.handler(packet, channelContext);
- }
- }
-
- /**
- * @see org.tio.core.intf.AioHandler#encode(org.tio.core.intf.Packet)
- *
- * @param packet
- * @return
- * @author: Wchao
- * 2016年11月18日 上午9:37:44
- *
- */
- @Override
- public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- AbstractProtocolHandler handler = (AbstractProtocolHandler)imSessionContext.getProtocolHandler();
- if(handler != null){
- return handler.encode(packet, groupContext, channelContext);
- }
- return null;
- }
-
- /**
- * @see org.tio.core.intf.AioHandler#decode(java.nio.ByteBuffer)
- *
- * @param buffer
- * @return
- * @throws AioDecodeException
- * @author: Wchao
- * 2016年11月18日 上午9:37:44
- *
- */
- @Override
- public Packet decode(ByteBuffer buffer,int limit, int position, int readableLength,ChannelContext channelContext) throws AioDecodeException {
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
- AbstractProtocolHandler handler = null;
- if(imSessionContext == null){
- handler = ProtocolHandlerManager.initServerHandlerToChannelContext(buffer, channelContext);
- ImServerGroupContext imGroupContext = (ImServerGroupContext)imConfig.getGroupContext();
- channelContext.setAttribute(ImConst.CHAT_QUEUE,new MsgQueueRunnable(channelContext,imGroupContext.getTimExecutor()));
- }else{
- handler = (AbstractProtocolHandler)imSessionContext.getProtocolHandler();
- }
- if(handler != null){
- return handler.decode(buffer, channelContext);
- }else{
- throw new AioDecodeException("不支持的协议类型,无法找到对应的协议解码器!");
- }
- }
-
- public ImConfig getImConfig() {
- return imConfig;
- }
- public void setImConfig(ImConfig imConfig) {
- this.imConfig = imConfig;
- }
-
-}
diff --git a/jim-server/src/main/java/org/jim/server/handler/ImServerHandler.java b/jim-server/src/main/java/org/jim/server/handler/ImServerHandler.java
new file mode 100644
index 0000000..f391c45
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/handler/ImServerHandler.java
@@ -0,0 +1,11 @@
+package org.jim.server.handler;
+
+import org.jim.common.ImHandler;
+/**
+ *
+ * @author WChao
+ *
+ */
+public interface ImServerHandler extends ImHandler {
+
+}
diff --git a/jim-server/src/main/java/org/jim/server/handler/ImServerHandlerAdapter.java b/jim-server/src/main/java/org/jim/server/handler/ImServerHandlerAdapter.java
new file mode 100644
index 0000000..51df9d9
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/handler/ImServerHandlerAdapter.java
@@ -0,0 +1,53 @@
+package org.jim.server.handler;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.ImPacket;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.server.ImServerChannelContext;
+import org.tio.core.ChannelContext;
+import org.tio.core.TioConfig;
+import org.tio.core.exception.AioDecodeException;
+import org.tio.core.intf.Packet;
+import org.tio.server.intf.ServerAioHandler;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @ClassName ImServerHandlerAdapter
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/6 2:30
+ * @Version 1.0
+ **/
+public class ImServerHandlerAdapter implements ServerAioHandler, ImConst{
+
+ private ImServerHandler imServerHandler;
+
+ public ImServerHandlerAdapter(ImServerHandler imServerHandler){
+ this.imServerHandler = imServerHandler;
+ }
+
+ @Override
+ public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
+ ImPacket imPacket;
+ try {
+ imPacket = this.imServerHandler.decode(buffer, limit, position, readableLength, (ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY));
+ }catch (ImDecodeException e) {
+ throw new AioDecodeException(e);
+ }
+ return imPacket;
+ }
+
+ @Override
+ public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
+ return this.imServerHandler.encode((ImPacket)packet, ImConfig.Global.get(), (ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY));
+ }
+
+ @Override
+ public void handler(Packet packet, ChannelContext channelContext) throws Exception {
+ this.imServerHandler.handler((ImPacket)packet, (ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY));
+ }
+
+}
diff --git a/jim-server/src/main/java/org/jim/server/handler/ProtocolHandlerManager.java b/jim-server/src/main/java/org/jim/server/handler/ProtocolHandlerManager.java
deleted file mode 100644
index 2d3d9be..0000000
--- a/jim-server/src/main/java/org/jim/server/handler/ProtocolHandlerManager.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- *
- */
-package org.jim.server.handler;
-
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-import org.jim.common.ImConfig;
-import org.jim.common.ImSessionContext;
-import org.jim.common.exception.ImException;
-import org.jim.common.protocol.IProtocol;
-import org.jim.common.utils.ImKit;
-import org.tio.core.ChannelContext;
-/**
- * 版本: [1.0]
- * 功能说明:
- * @author : WChao 创建时间: 2017年8月3日 下午2:40:24
- */
-public class ProtocolHandlerManager{
-
- private static Logger logger = Logger.getLogger(ProtocolHandlerManager.class);
-
- private static Map serverHandlers = new HashMap();
-
- static{
- try {
- List configurations = ProtocolHandlerConfigurationFactory.parseConfiguration();
- init(configurations);
- } catch (Exception e) {
- logger.error(e.toString(),e);
- }
- }
-
- private static void init(List configurations) throws Exception{
- for(ProtocolHandlerConfiguration configuration : configurations){
- Class serverHandlerClazz = (Class)Class.forName(configuration.getServerHandler());
- AbstractProtocolHandler serverHandler = serverHandlerClazz.newInstance();
- addServerHandler(serverHandler);
- }
- }
-
- public static AbstractProtocolHandler addServerHandler(AbstractProtocolHandler serverHandler)throws ImException{
- if(Objects.isNull(serverHandler)){
- throw new ImException("ProtocolHandler must not null ");
- }
- return serverHandlers.put(serverHandler.protocol().name(),serverHandler);
- }
-
- public static AbstractProtocolHandler removeServerHandler(String name)throws ImException{
- if(StringUtils.isEmpty(name)){
- throw new ImException("server name must not empty");
- }
- return serverHandlers.remove(name);
- }
-
- public static AbstractProtocolHandler initServerHandlerToChannelContext(ByteBuffer buffer, ChannelContext channelContext){
- IProtocol protocol = ImKit.protocol(buffer, channelContext);
- for(Entry entry : serverHandlers.entrySet()){
- AbstractProtocolHandler protocolHandler = entry.getValue();
- String protocolName = protocolHandler.protocol().name();
- try {
- if(protocol != null && protocol.name().equals(protocolName)){
- ImSessionContext sessionContext = (ImSessionContext)channelContext.getAttribute();
- sessionContext.setProtocolHandler(protocolHandler);
- channelContext.setAttribute(sessionContext);
- return protocolHandler;
- }
- } catch (Throwable e) {
- logger.error(e);
- }
- }
- return null;
- }
-
- public static T getServerHandler(String name,Class clazz){
- AbstractProtocolHandler serverHandler = serverHandlers.get(name);
- if(Objects.isNull(serverHandler)) {
- return null;
- }
- return (T)serverHandler;
- }
-
- public static void init(ImConfig imConfig){
- for(Entry entry : serverHandlers.entrySet()){
- try {
- entry.getValue().init(imConfig);
- } catch (Exception e) {
- logger.error(e);
- }
- }
- }
-}
diff --git a/jim-server/src/main/java/org/jim/server/handler/ProtocolManager.java b/jim-server/src/main/java/org/jim/server/handler/ProtocolManager.java
new file mode 100644
index 0000000..4d98c6b
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/handler/ProtocolManager.java
@@ -0,0 +1,194 @@
+/**
+ *
+ */
+package org.jim.server.handler;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.ImPacket;
+import org.jim.common.ImStatus;
+import org.jim.common.exception.ImException;
+import org.jim.common.packets.Command;
+import org.jim.common.packets.RespBody;
+import org.jim.common.protocol.IProtocolConverter;
+import org.jim.common.utils.ImKit;
+import org.jim.server.ImServerChannelContext;
+import org.jim.server.config.ImServerConfig;
+/**
+ * 版本: [1.0]
+ * 功能说明:
+ * @author : WChao 创建时间: 2017年8月3日 下午2:40:24
+ */
+public class ProtocolManager implements ImConst{
+
+ private static Logger logger = Logger.getLogger(ProtocolManager.class);
+
+ private static Map serverHandlers = new HashMap();
+
+ static{
+ try {
+ List configurations = ProtocolHandlerConfigurationFactory.parseConfiguration();
+ init(configurations);
+ } catch (Exception e) {
+ logger.error(e.toString(),e);
+ }
+ }
+
+ private static void init(List configurations) throws Exception{
+ for(ProtocolHandlerConfiguration configuration : configurations){
+ Class serverHandlerClazz = (Class)Class.forName(configuration.getServerHandler());
+ AbstractProtocolHandler serverHandler = serverHandlerClazz.newInstance();
+ addServerHandler(serverHandler);
+ }
+ }
+
+ public static AbstractProtocolHandler addServerHandler(AbstractProtocolHandler serverHandler)throws ImException{
+ if(Objects.isNull(serverHandler)){
+ throw new ImException("ProtocolHandler must not null ");
+ }
+ return serverHandlers.put(serverHandler.getProtocol().name(),serverHandler);
+ }
+
+ public static AbstractProtocolHandler removeServerHandler(String name)throws ImException{
+ if(StringUtils.isEmpty(name)){
+ throw new ImException("server name must not empty");
+ }
+ return serverHandlers.remove(name);
+ }
+
+ public static AbstractProtocolHandler initProtocolHandler(ByteBuffer buffer, ImChannelContext imChannelContext){
+ ImServerChannelContext imServerChannelContext = (ImServerChannelContext)imChannelContext;
+ for(Entry entry : serverHandlers.entrySet()){
+ AbstractProtocolHandler protocolHandler = entry.getValue();
+ try {
+ if(protocolHandler.getProtocol().isProtocol(buffer, imServerChannelContext)){
+ imServerChannelContext.setProtocolHandler(protocolHandler);
+ return protocolHandler;
+ }
+ } catch (Throwable e) {
+ logger.error(e);
+ }
+ }
+ return null;
+ }
+
+ public static T getServerHandler(String name,Class clazz){
+ AbstractProtocolHandler serverHandler = serverHandlers.get(name);
+ if(Objects.isNull(serverHandler)) {
+ return null;
+ }
+ return (T)serverHandler;
+ }
+
+ public static void init(){
+ init((ImServerConfig)ImServerConfig.Global.get());
+ }
+ public static void init(ImServerConfig imServerConfig){
+ for(Entry entry : serverHandlers.entrySet()){
+ try {
+ entry.getValue().init(imServerConfig);
+ } catch (Exception e) {
+ logger.error(e);
+ }
+ }
+ }
+
+ public static class Converter{
+
+ /**
+ * 功能描述:[转换不同协议响应包]
+ * @author:WChao 创建时间: 2017年9月21日 下午3:21:54
+ * @param respBody
+ * @param channelContext
+ * @return
+ *
+ */
+ public static ImPacket respPacket(RespBody respBody, ImChannelContext channelContext)throws ImException {
+ if(Objects.isNull(respBody)) {
+ throw new ImException("响应包体不能为空!");
+ }
+ return respPacket(respBody.toByte(), respBody.getCommand(), channelContext);
+ }
+
+ /**
+ * 功能描述:[转换不同协议响应包]
+ * @author:WChao 创建时间: 2017年9月21日 下午3:21:54
+ * @param body
+ * @param channelContext
+ * @return
+ *
+ */
+ public static ImPacket respPacket(byte[] body, Command command, ImChannelContext channelContext)throws ImException{
+ ImServerChannelContext serverChannelContext = (ImServerChannelContext)channelContext;
+ AbstractProtocolHandler protocolHandler = serverChannelContext.getProtocolHandler();
+ if(Objects.isNull(protocolHandler)){
+ throw new ImException("协议[ProtocolHandler]未初始化,协议包转化失败");
+ }
+ IProtocolConverter converter = protocolHandler.getProtocol().getConverter();
+ if(converter != null){
+ return converter.RespPacket(body, command, channelContext);
+ }else {
+ throw new ImException("未获取到协议转化器[ProtocolConverter]");
+ }
+ }
+
+ public static ImPacket respPacket(ImPacket imPacket, ImChannelContext channelContext)throws ImException{
+ return respPacket(imPacket, imPacket.getCommand(), channelContext);
+ }
+
+ public static ImPacket respPacket(ImPacket imPacket,Command command, ImChannelContext channelContext)throws ImException{
+ return respPacket(imPacket.getBody(), command, channelContext);
+ }
+
+ }
+
+ public static class Packet{
+ /**
+ * 数据格式不正确响应包
+ * @param imChannelContext
+ * @return imPacket
+ * @throws ImException
+ */
+ public static ImPacket dataInCorrect(ImChannelContext imChannelContext) throws ImException{
+ RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10002);
+ ImPacket respPacket = Converter.respPacket(chatDataInCorrectRespPacket, imChannelContext);
+ respPacket.setStatus(ImStatus.C10002);
+ return respPacket;
+ }
+
+ /**
+ * 发送成功响应包
+ * @param imChannelContext
+ * @return imPacket
+ * @throws ImException
+ */
+ public static ImPacket success(ImChannelContext imChannelContext) throws ImException{
+ RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP, ImStatus.C10000);
+ ImPacket respPacket = Converter.respPacket(chatDataInCorrectRespPacket, imChannelContext);
+ respPacket.setStatus(ImStatus.C10000);
+ return respPacket;
+ }
+
+ /**
+ * 用户不在线响应包
+ * @param imChannelContext
+ * @return
+ * @throws ImException
+ */
+ public static ImPacket offline(ImChannelContext imChannelContext) throws ImException{
+ RespBody chatDataInCorrectRespPacket = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10001);
+ ImPacket respPacket = Converter.respPacket(chatDataInCorrectRespPacket, imChannelContext);
+ respPacket.setStatus(ImStatus.C10001);
+ return respPacket;
+ }
+ }
+}
diff --git a/jim-server/src/main/java/org/jim/server/helper/redis/RedisImBindListener.java b/jim-server/src/main/java/org/jim/server/helper/redis/RedisImBindListener.java
index 0746ced..be3b97e 100644
--- a/jim-server/src/main/java/org/jim/server/helper/redis/RedisImBindListener.java
+++ b/jim-server/src/main/java/org/jim/server/helper/redis/RedisImBindListener.java
@@ -1,17 +1,18 @@
package org.jim.server.helper.redis;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConfig;
+import org.jim.common.ImChannelContext;
+import org.jim.common.config.ImConfig;
import org.jim.common.ImSessionContext;
import org.jim.common.cache.redis.RedisCache;
import org.jim.common.cache.redis.RedisCacheManager;
+import org.jim.common.exception.ImException;
import org.jim.common.listener.AbstractImBindListener;
import org.jim.common.packets.Client;
import org.jim.common.packets.Group;
import org.jim.common.packets.User;
import org.jim.common.utils.ImKit;
-import org.tio.core.ChannelContext;
-
+import org.jim.server.config.ImServerConfig;
import java.io.Serializable;
import java.util.List;
/**
@@ -21,9 +22,9 @@ import java.util.List;
*/
public class RedisImBindListener extends AbstractImBindListener{
- private RedisCache groupCache = null;
- private RedisCache userCache = null;
- private final String SUBFIX = ":";
+ private RedisCache groupCache;
+ private RedisCache userCache;
+ private final String SUFFIX = ":";
public RedisImBindListener(){
this(null);
@@ -40,49 +41,48 @@ public class RedisImBindListener extends AbstractImBindListener{
RedisCacheManager.register(GROUP, Integer.MAX_VALUE, Integer.MAX_VALUE);
RedisCacheManager.register(STORE, Integer.MAX_VALUE, Integer.MAX_VALUE);
RedisCacheManager.register(PUSH, Integer.MAX_VALUE, Integer.MAX_VALUE);
-
}
@Override
- public void onAfterGroupBind(ChannelContext channelContext, String group) throws Exception {
+ public void onAfterGroupBind(ImChannelContext imChannelContext, String group) throws ImException {
if(!isStore()) {
return;
}
- initGroupUsers(group,channelContext);
+ initGroupUsers(group, imChannelContext);
}
@Override
- public void onAfterGroupUnbind(ChannelContext channelContext, String group) throws Exception {
+ public void onAfterGroupUnbind(ImChannelContext imChannelContext, String group) throws ImException {
if(!isStore()) {
return;
}
- String userid = channelContext.getUserid();
+ String userId = imChannelContext.getUserId();
//移除群组成员;
- groupCache.listRemove(group+SUBFIX+USER, userid);
+ groupCache.listRemove(group+SUFFIX+USER, userId);
//移除成员群组;
- userCache.listRemove(userid+SUBFIX+GROUP, group);
- RedisCacheManager.getCache(PUSH).remove(GROUP+SUBFIX+group+SUBFIX+userid);
+ userCache.listRemove(userId+SUFFIX+GROUP, group);
+ RedisCacheManager.getCache(PUSH).remove(GROUP+SUFFIX+group+SUFFIX+userId);
}
@Override
- public void onAfterUserBind(ChannelContext channelContext, String userid) throws Exception {
+ public void onAfterUserBind(ImChannelContext imChannelContext, String userId) throws ImException {
if(!isStore()) {
return;
}
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
Client client = imSessionContext.getClient();
if(client == null) {
return;
}
User onlineUser = client.getUser();
if(onlineUser != null){
- initUserTerminal(channelContext,onlineUser.getTerminal(),ONLINE);
+ initUserTerminal(imChannelContext,onlineUser.getTerminal(),ONLINE);
initUserInfo(onlineUser);
}
}
@Override
- public void onAfterUserUnbind(ChannelContext channelContext, String userid) throws Exception {
+ public void onAfterUserUnbind(ImChannelContext imChannelContext, String userId) throws ImException {
if(!isStore()) {
return;
}
@@ -91,24 +91,24 @@ public class RedisImBindListener extends AbstractImBindListener{
/**
* 初始化群组用户;
* @param groupId
- * @param channelContext
+ * @param imChannelContext
*/
- public void initGroupUsers(String groupId ,ChannelContext channelContext){
+ public void initGroupUsers(String groupId ,ImChannelContext imChannelContext){
if(!isStore()) {
return;
}
- String userId = channelContext.getUserid();
+ String userId = imChannelContext.getUserId();
if(StringUtils.isEmpty(groupId) || StringUtils.isEmpty(userId)) {
return;
}
- String group_user_key = groupId+SUBFIX+USER;
+ String group_user_key = groupId+SUFFIX+USER;
List users = groupCache.listGetAll(group_user_key);
if(!users.contains(userId)){
groupCache.listPushTail(group_user_key, userId);
}
initUserGroups(userId, groupId);
- ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+ ImSessionContext imSessionContext = imChannelContext.getSessionContext();
Client client = imSessionContext.getClient();
if(client == null) {
return;
@@ -123,44 +123,44 @@ public class RedisImBindListener extends AbstractImBindListener{
}
for(Group group : groups){
if(groupId.equals(group.getGroup_id())){
- groupCache.put(groupId+SUBFIX+INFO, group);
+ groupCache.put(groupId+SUFFIX+INFO, group);
break;
}
}
}
/**
* 初始化用户拥有哪些群组;
- * @param userid
+ * @param userId
* @param group
*/
- public void initUserGroups(String userid, String group){
+ public void initUserGroups(String userId, String group){
if(!isStore()) {
return;
}
- if(StringUtils.isEmpty(group) || StringUtils.isEmpty(userid)) {
+ if(StringUtils.isEmpty(group) || StringUtils.isEmpty(userId)) {
return;
}
- List groups = userCache.listGetAll(userid+SUBFIX+GROUP);
+ List groups = userCache.listGetAll(userId+SUFFIX+GROUP);
if(!groups.contains(group)){
- userCache.listPushTail(userid+SUBFIX+GROUP, group);
+ userCache.listPushTail(userId+SUFFIX+GROUP, group);
}
}
/**
* 初始化用户终端协议类型;
- * @param channelContext
+ * @param imChannelContext
* @param terminal
* @param status(online、offline)
*/
@Override
- public void initUserTerminal(ChannelContext channelContext , String terminal , String status){
+ public void initUserTerminal(ImChannelContext imChannelContext , String terminal , String status){
if(!isStore()) {
return;
}
- String userId = channelContext.getUserid();
+ String userId = imChannelContext.getUserId();
if(StringUtils.isEmpty(userId) || StringUtils.isEmpty(terminal)) {
return;
}
- userCache.put(userId+SUBFIX+TERMINAL+SUBFIX+terminal, status);
+ userCache.put(userId+SUFFIX+TERMINAL+SUFFIX+terminal, status);
}
/**
* 初始化用户终端协议类型;
@@ -175,10 +175,10 @@ public class RedisImBindListener extends AbstractImBindListener{
return;
}
User userCopy = ImKit.copyUserWithoutFriendsGroups(user);
- userCache.put(userId+SUBFIX+INFO, userCopy);
+ userCache.put(userId+SUFFIX+INFO, userCopy);
List friends = user.getFriends();
if(friends != null){
- userCache.put(userId+SUBFIX+FRIENDS, (Serializable) friends);
+ userCache.put(userId+SUFFIX+FRIENDS, (Serializable) friends);
}
}
/**
@@ -186,6 +186,7 @@ public class RedisImBindListener extends AbstractImBindListener{
* @return
*/
public boolean isStore(){
- return ON.equals(imConfig.getIsStore());
+ ImServerConfig imServerConfig = (ImServerConfig)imConfig;
+ return ImConfig.Const.ON.equals(imServerConfig.getIsStore());
}
}
diff --git a/jim-server/src/main/java/org/jim/server/helper/redis/RedisMessageHelper.java b/jim-server/src/main/java/org/jim/server/helper/redis/RedisMessageHelper.java
index 57b753e..e1b7c6c 100644
--- a/jim-server/src/main/java/org/jim/server/helper/redis/RedisMessageHelper.java
+++ b/jim-server/src/main/java/org/jim/server/helper/redis/RedisMessageHelper.java
@@ -3,7 +3,7 @@ package org.jim.server.helper.redis;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.jim.common.ImConfig;
+import org.jim.common.config.ImConfig;
import org.jim.common.cache.redis.JedisTemplate;
import org.jim.common.cache.redis.RedisCache;
import org.jim.common.cache.redis.RedisCacheManager;
@@ -47,9 +47,6 @@ public class RedisMessageHelper extends AbstractMessageHelper{
}
public RedisMessageHelper(){
- this(null);
- }
- public RedisMessageHelper(ImConfig imConfig){
this.groupCache = RedisCacheManager.getCache(GROUP);
this.pushCache = RedisCacheManager.getCache(PUSH);
this.storeCache = RedisCacheManager.getCache(STORE);
diff --git a/jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java b/jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java
index 209ad91..24de490 100644
--- a/jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java
+++ b/jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java
@@ -10,12 +10,13 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import org.apache.commons.lang3.StringUtils;
+import org.jim.common.ImConst;
+import org.jim.common.exception.ImException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.jim.common.http.Cookie;
import org.jim.common.http.HttpConfig;
-import org.jim.common.http.HttpConst;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpResponse;
import org.jim.common.http.HttpResponseStatus;
@@ -38,16 +39,9 @@ import cn.hutool.core.util.ClassUtil;
* @author WChao
*
*/
-public class DefaultHttpRequestHandler implements IHttpRequestHandler {
+public class DefaultHttpRequestHandler implements IHttpRequestHandler,ImConst.Http {
private static Logger log = LoggerFactory.getLogger(DefaultHttpRequestHandler.class);
- // /**
- // * 静态资源的CacheName
- // * key: path 譬如"/index.html"
- // * value: HttpResponse
- // */
- // private static final String STATIC_RES_CACHENAME = "TIO_HTTP_STATIC_RES";
-
/**
* 静态资源的CacheName
* key: path 譬如"/index.html"
@@ -55,22 +49,10 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
*/
private static final String STATIC_RES_CONTENT_CACHENAME = "TIO_HTTP_STATIC_RES_CONTENT";
- /**
- * @param args
- *
- * @author WChao
- * 2016年11月18日 上午9:13:15
- *
- */
- public static void main(String[] args) {
- }
-
protected HttpConfig httpConfig;
protected Routes routes = null;
- // private LoadingCache loadingCache = null;
-
private IHttpServerListener httpServerListener;
private GuavaCache staticResCache;
@@ -84,7 +66,6 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
this.httpConfig = httpConfig;
if (httpConfig.getMaxLiveTimeOfStaticRes() > 0) {
- // GuavaCache.register(STATIC_RES_CACHENAME, (long) httpConfig.getMaxLiveTimeOfStaticRes(), null);
staticResCache = GuavaCache.register(STATIC_RES_CONTENT_CACHENAME, (long) httpConfig.getMaxLiveTimeOfStaticRes(), null);
}
this.setHttpServerListener(httpConfig.getHttpServerListener());
@@ -102,7 +83,7 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
}
/**
- * 创建httpsession
+ * 创建httpSession
* @return
* @author WChao
*/
@@ -136,11 +117,11 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
}
@Override
- public HttpResponse handler(HttpRequest request, RequestLine requestLine) throws Exception {
+ public HttpResponse handler(HttpRequest request, RequestLine requestLine) throws ImException {
HttpResponse ret = null;
try {
processCookieBeforeHandler(request, requestLine);
- HttpSession httpSession = request.getHttpSession();//(HttpSession) channelContext.getAttribute();
+ HttpSession httpSession = request.getHttpSession();
if (httpServerListener != null) {
ret = httpServerListener.doBeforeHandler(request, requestLine, ret);
@@ -175,7 +156,7 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
} else if (paramType.isAssignableFrom(HttpConfig.class)) {
paramValues[i] = httpConfig;
} else if (paramType.isAssignableFrom(ChannelContext.class)) {
- paramValues[i] = request.getChannelContext();
+ paramValues[i] = request.getImChannelContext();
} else {
if (params != null) {
if (ClassUtils.isSimpleTypeOrArray(paramType)) {
@@ -188,7 +169,8 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
}
}
} else {
- paramValues[i] = paramType.newInstance();//BeanUtil.mapToBean(params, paramType, true);
+ //BeanUtil.mapToBean(params, paramType, true);
+ paramValues[i] = paramType.newInstance();
Set> set = params.entrySet();
label2: for (Entry entry : set) {
String fieldName = entry.getKey();
@@ -254,7 +236,7 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
ret = HttpResps.try304(request, lastModified);
if (ret != null) {
- ret.addHeader(HttpConst.ResponseHeaderKey.tio_from_cache, "true");
+ ret.addHeader(ResponseHeaderKey.tio_from_cache, "true");
return ret;
}
@@ -281,21 +263,21 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
if (contentCache != null && request.getIsSupportGzip()) {
if (ret.getBody() != null && ret.getStatus() == HttpResponseStatus.C200) {
- String contentType = ret.getHeader(HttpConst.ResponseHeaderKey.Content_Type);
- String contentEncoding = ret.getHeader(HttpConst.ResponseHeaderKey.Content_Encoding);
- String lastModified = ret.getHeader(HttpConst.ResponseHeaderKey.Last_Modified);
+ String contentType = ret.getHeader(ResponseHeaderKey.Content_Type);
+ String contentEncoding = ret.getHeader(ResponseHeaderKey.Content_Encoding);
+ String lastModified = ret.getHeader(ResponseHeaderKey.Last_Modified);
Map headers = new HashMap<>();
if (StringUtils.isNotBlank(contentType)) {
- headers.put(HttpConst.ResponseHeaderKey.Content_Type, contentType);
+ headers.put(ResponseHeaderKey.Content_Type, contentType);
}
if (StringUtils.isNotBlank(contentEncoding)) {
- headers.put(HttpConst.ResponseHeaderKey.Content_Encoding, contentEncoding);
+ headers.put(ResponseHeaderKey.Content_Encoding, contentEncoding);
}
if (StringUtils.isNotBlank(lastModified)) {
- headers.put(HttpConst.ResponseHeaderKey.Last_Modified, lastModified);
+ headers.put(ResponseHeaderKey.Last_Modified, lastModified);
}
- headers.put(HttpConst.ResponseHeaderKey.tio_from_cache, "true");
+ headers.put(ResponseHeaderKey.tio_from_cache, "true");
fileCache = new FileCache(headers, file.lastModified(), ret.getBody());
contentCache.put(initPath, fileCache);
@@ -342,24 +324,22 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
String sessionId = null;
if (cookie == null) {
- String domain = request.getHeader(HttpConst.RequestHeaderKey.Host);
+ String domain = request.getHeader(RequestHeaderKey.Host);
String name = httpConfig.getSessionCookieName();
long maxAge = httpConfig.getSessionTimeout();
- // maxAge = Integer.MAX_VALUE; //把过期时间掌握在服务器端
-
- sessionId = httpSession.getId();//randomCookieValue();
+ sessionId = httpSession.getId();
cookie = new Cookie(domain, name, sessionId, maxAge);
httpResponse.addCookie(cookie);
httpConfig.getSessionStore().put(sessionId, httpSession);
- log.info("{} 创建会话Cookie, {}", request.getChannelContext(), cookie);
+ log.info("{} 创建会话Cookie, {}", request.getImChannelContext(), cookie);
} else {
sessionId = cookie.getValue();
HttpSession httpSession1 = (HttpSession) httpConfig.getSessionStore().get(sessionId);
if (httpSession1 == null) {//有cookie但是超时了
sessionId = httpSession.getId();
- String domain = request.getHeader(HttpConst.RequestHeaderKey.Host);
+ String domain = request.getHeader(RequestHeaderKey.Host);
String name = httpConfig.getSessionCookieName();
long maxAge = httpConfig.getSessionTimeout();
// maxAge = Long.MAX_VALUE; //把过期时间掌握在服务器端
@@ -381,7 +361,7 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
String sessionId = cookie.getValue();
httpSession = (HttpSession) httpConfig.getSessionStore().get(sessionId);
if (httpSession == null) {
- log.info("{} session【{}】超时", request.getChannelContext(), sessionId);
+ log.info("{} session【{}】超时", request.getImChannelContext(), sessionId);
httpSession = createSession();
}
}
diff --git a/jim-server/src/main/java/org/jim/server/http/HttpProtocolHandler.java b/jim-server/src/main/java/org/jim/server/http/HttpProtocolHandler.java
index 0231fe0..5d1e02c 100644
--- a/jim-server/src/main/java/org/jim/server/http/HttpProtocolHandler.java
+++ b/jim-server/src/main/java/org/jim/server/http/HttpProtocolHandler.java
@@ -3,36 +3,34 @@
*/
package org.jim.server.http;
-import org.jim.common.ImConfig;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
-import org.jim.common.http.GroupContextKey;
-import org.jim.common.http.HttpConfig;
-import org.jim.common.http.HttpProtocol;
-import org.jim.common.http.HttpRequest;
-import org.jim.common.http.HttpRequestDecoder;
-import org.jim.common.http.HttpResponse;
-import org.jim.common.http.HttpResponseEncoder;
+import org.jim.common.ImPacket;
+import org.jim.common.Jim;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.common.exception.ImException;
+import org.jim.common.http.*;
import org.jim.common.http.handler.IHttpRequestHandler;
+import org.jim.common.protocol.AbstractProtocol;
import org.jim.common.protocol.IProtocol;
import org.jim.common.session.id.impl.UUIDSessionIdGenerator;
import org.jim.server.ImServerStarter;
+import org.jim.server.config.ImServerConfig;
import org.jim.server.handler.AbstractProtocolHandler;
import org.jim.server.http.mvc.Routes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
-import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-import org.tio.core.exception.AioDecodeException;
-import org.tio.core.intf.Packet;
import org.tio.utils.SystemTimer;
import org.tio.utils.cache.guava.GuavaCache;
import java.nio.ByteBuffer;
+import java.util.Objects;
+
/**
* 版本: [1.0]
* 功能说明:
- * 作者: WChao 创建时间: 2017年8月3日 下午3:07:54
+ * @author : WChao 创建时间: 2017年8月3日 下午3:07:54
*/
public class HttpProtocolHandler extends AbstractProtocolHandler {
@@ -41,27 +39,28 @@ public class HttpProtocolHandler extends AbstractProtocolHandler {
private HttpConfig httpConfig;
private IHttpRequestHandler httpRequestHandler;
-
- public HttpProtocolHandler() {}
-
- public HttpProtocolHandler(HttpConfig httpServerConfig){
- this.httpConfig = httpServerConfig;
+
+ public HttpProtocolHandler(){
+ this(null, new HttpProtocol(new HttpConvertPacket()));
+ };
+
+ public HttpProtocolHandler(HttpConfig httpConfig, AbstractProtocol protocol){
+ super(protocol);
+ this.httpConfig = httpConfig;
}
+
@Override
- public void init(ImConfig imConfig)throws Exception{
+ public void init(ImServerConfig imConfig)throws ImException {
long start = SystemTimer.currentTimeMillis();
this.httpConfig = imConfig.getHttpConfig();
- if (httpConfig.getSessionStore() == null) {
+ if (Objects.isNull(httpConfig.getSessionStore())) {
GuavaCache guavaCache = GuavaCache.register(httpConfig.getSessionCacheName(), null, httpConfig.getSessionTimeout());
httpConfig.setSessionStore(guavaCache);
}
- if (httpConfig.getPageRoot() == null) {
- httpConfig.setPageRoot("page");
- }
- if (httpConfig.getSessionIdGenerator() == null) {
+ if (Objects.isNull(httpConfig.getSessionIdGenerator())) {
httpConfig.setSessionIdGenerator(UUIDSessionIdGenerator.instance);
}
- if(httpConfig.getScanPackages() == null){
+ if(Objects.isNull(httpConfig.getScanPackages())){
//J-IM MVC需要扫描的根目录包
String[] scanPackages = new String[] { ImServerStarter.class.getPackage().getName() };
httpConfig.setScanPackages(scanPackages);
@@ -74,30 +73,29 @@ public class HttpProtocolHandler extends AbstractProtocolHandler {
Routes routes = new Routes(httpConfig.getScanPackages());
httpRequestHandler = new DefaultHttpRequestHandler(httpConfig, routes);
httpConfig.setHttpRequestHandler(httpRequestHandler);
- imConfig.getGroupContext().setAttribute(GroupContextKey.HTTP_SERVER_CONFIG, httpConfig);
long end = SystemTimer.currentTimeMillis();
long iv = end - start;
- log.info("J-IM Http Server初始化完毕,耗时:{}ms", iv);
+ log.info("J-IM Http协议初始化完毕,耗时:{}ms", iv);
}
@Override
- public ByteBuffer encode(Packet packet, GroupContext groupContext,ChannelContext channelContext) {
- HttpResponse httpResponsePacket = (HttpResponse) packet;
- ByteBuffer byteBuffer = HttpResponseEncoder.encode(httpResponsePacket, groupContext, channelContext,false);
+ public ByteBuffer encode(ImPacket imPacket, ImConfig imConfig, ImChannelContext imChannelContext) {
+ HttpResponse httpResponsePacket = (HttpResponse) imPacket;
+ ByteBuffer byteBuffer = HttpResponseEncoder.encode(httpResponsePacket, imChannelContext,false);
return byteBuffer;
}
@Override
- public void handler(Packet packet, ChannelContext channelContext)throws Exception {
- HttpRequest httpRequestPacket = (HttpRequest) packet;
+ public void handler(ImPacket imPacket, ImChannelContext imChannelContext)throws ImException {
+ HttpRequest httpRequestPacket = (HttpRequest) imPacket;
HttpResponse httpResponsePacket = httpRequestHandler.handler(httpRequestPacket, httpRequestPacket.getRequestLine());
- Aio.send(channelContext, httpResponsePacket);
+ Jim.send(imChannelContext, httpResponsePacket);
}
@Override
- public Packet decode(ByteBuffer buffer, ChannelContext channelContext)throws AioDecodeException {
- HttpRequest request = HttpRequestDecoder.decode(buffer, channelContext,true);
- channelContext.setAttribute(ImConst.HTTP_REQUEST,request);
+ public ImPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ImChannelContext imChannelContext)throws ImDecodeException {
+ HttpRequest request = HttpRequestDecoder.decode(buffer, imChannelContext,true);
+ imChannelContext.setAttribute(ImConst.HTTP_REQUEST,request);
return request;
}
@@ -117,8 +115,4 @@ public class HttpProtocolHandler extends AbstractProtocolHandler {
this.httpConfig = httpConfig;
}
- @Override
- public IProtocol protocol() {
- return new HttpProtocol();
- }
}
diff --git a/jim-server/src/main/java/org/jim/server/http/api/HttpApiController.java b/jim-server/src/main/java/org/jim/server/http/api/HttpApiController.java
index 2bb4fbd..2c5fe42 100644
--- a/jim-server/src/main/java/org/jim/server/http/api/HttpApiController.java
+++ b/jim-server/src/main/java/org/jim/server/http/api/HttpApiController.java
@@ -3,7 +3,8 @@
*/
package org.jim.server.http.api;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
import org.jim.common.http.HttpConfig;
@@ -28,7 +29,7 @@ import org.tio.core.ChannelContext;
public class HttpApiController {
@RequestPath(value = "/message/send")
- public HttpResponse chat(HttpRequest request, HttpConfig httpConfig, ChannelContext channelContext)throws Exception {
+ public HttpResponse chat(HttpRequest request, HttpConfig httpConfig, ImChannelContext channelContext)throws Exception {
HttpResponse response = new HttpResponse(request,httpConfig);
ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ,ChatReqHandler.class);
ImPacket chatPacket = chatReqHandler.handler(request, channelContext);
@@ -52,7 +53,7 @@ public class HttpApiController {
return HttpResps.json(request, new RespBody(ImStatus.C10020));
}
String userId = params[0].toString();
- User user = ImAio.getUser(userId);
+ User user = null/*Jim.getUser(userId)*/;
if(user != null){
return HttpResps.json(request, new RespBody(ImStatus.C10019));
}else{
@@ -68,7 +69,7 @@ public class HttpApiController {
* @throws Exception
*/
@RequestPath(value = "user/close")
- public HttpResponse close(HttpRequest request, HttpConfig httpConfig, ChannelContext channelContext)throws Exception {
+ public HttpResponse close(HttpRequest request, HttpConfig httpConfig, ImChannelContext channelContext)throws Exception {
Object[] params = request.getParams().get("userid");
if(params == null || params.length == 0){
return HttpResps.json(request, new RespBody(ImStatus.C10020));
diff --git a/jim-server/src/main/java/org/jim/server/listener/DefaultImServerListener.java b/jim-server/src/main/java/org/jim/server/listener/DefaultImServerListener.java
new file mode 100644
index 0000000..71cbbdc
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/listener/DefaultImServerListener.java
@@ -0,0 +1,54 @@
+package org.jim.server.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImPacket;
+import org.jim.common.ImStatus;
+import org.jim.common.Jim;
+import org.jim.common.packets.Command;
+import org.jim.common.packets.RespBody;
+import org.jim.server.handler.ProtocolManager;
+
+/**
+ * @ClassName DefaultImServerListener
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/4 11:15
+ * @Version 1.0
+ **/
+public class DefaultImServerListener implements ImServerListener {
+
+
+ @Override
+ public boolean onHeartbeatTimeout(ImChannelContext channelContext, Long interval, int heartbeatTimeoutCount) {
+ return false;
+ }
+
+ @Override
+ public void onAfterConnected(ImChannelContext channelContext, boolean isConnected, boolean isReconnect) throws Exception {
+
+ }
+
+ @Override
+ public void onAfterDecoded(ImChannelContext channelContext, ImPacket packet, int packetSize) throws Exception {
+
+ }
+
+ @Override
+ public void onAfterReceivedBytes(ImChannelContext channelContext, int receivedBytes) throws Exception {
+
+ }
+
+ @Override
+ public void onAfterSent(ImChannelContext channelContext, ImPacket packet, boolean isSentSuccess) throws Exception {
+
+ }
+
+ @Override
+ public void onAfterHandled(ImChannelContext channelContext, ImPacket packet, long cost) throws Exception {
+
+ }
+
+ @Override
+ public void onBeforeClose(ImChannelContext channelContext, Throwable throwable, String remark, boolean isRemove) throws Exception {
+ }
+}
diff --git a/jim-server/src/main/java/org/jim/server/listener/ImGroupListener.java b/jim-server/src/main/java/org/jim/server/listener/ImGroupListener.java
deleted file mode 100644
index 3ca6e6b..0000000
--- a/jim-server/src/main/java/org/jim/server/listener/ImGroupListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.jim.server.listener;
-
-import org.tio.core.ChannelContext;
-import org.tio.core.intf.GroupListener;
-/**
- * 绑定群组监听器
- * @author WChao
- * 2017年5月13日 下午10:38:36
- */
-public class ImGroupListener implements GroupListener{
-
- /**
- * 默认构造器
- */
- public ImGroupListener() {}
-
- /**
- * 绑定回调方法
- * @param channelContext
- * @param group
- * @throws Exception
- */
- @Override
- public void onAfterBind(ChannelContext channelContext, String group) throws Exception {
- }
-
- /**
- * 解绑回调方法
- * @param channelContext
- * @param group
- * @throws Exception
- */
- @Override
- public void onAfterUnbind(ChannelContext channelContext, String group) throws Exception {
- }
-}
diff --git a/jim-server/src/main/java/org/jim/server/listener/ImServerListener.java b/jim-server/src/main/java/org/jim/server/listener/ImServerListener.java
new file mode 100644
index 0000000..aff1654
--- /dev/null
+++ b/jim-server/src/main/java/org/jim/server/listener/ImServerListener.java
@@ -0,0 +1,24 @@
+package org.jim.server.listener;
+
+import org.jim.common.ImChannelContext;
+import org.jim.common.listener.ImListener;
+import org.tio.core.ChannelContext;
+
+/**
+ * @ClassName ImServerListener
+ * @Description TODO
+ * @Author WChao
+ * @Date 2020/1/4 9:35
+ * @Version 1.0
+ **/
+public interface ImServerListener extends ImListener {
+ /**
+ *
+ * 服务器检查到心跳超时时,会调用这个函数(一般场景,该方法只需要直接返回false即可)
+ * @param imChannelContext
+ * @param interval 已经多久没有收发消息了,单位:毫秒
+ * @param heartbeatTimeoutCount 心跳超时次数,第一次超时此值是1,以此类推。此值被保存在:channelContext.stat.heartbeatTimeoutCount
+ * @return 返回true,那么服务器则不关闭此连接;返回false,服务器将按心跳超时关闭该连接
+ */
+ boolean onHeartbeatTimeout(ImChannelContext imChannelContext, Long interval, int heartbeatTimeoutCount);
+}
diff --git a/jim-server/src/main/java/org/jim/server/listener/ImServerAioListener.java b/jim-server/src/main/java/org/jim/server/listener/ImServerListenerAdapter.java
similarity index 56%
rename from jim-server/src/main/java/org/jim/server/listener/ImServerAioListener.java
rename to jim-server/src/main/java/org/jim/server/listener/ImServerListenerAdapter.java
index 165f13c..5e79f74 100644
--- a/jim-server/src/main/java/org/jim/server/listener/ImServerAioListener.java
+++ b/jim-server/src/main/java/org/jim/server/listener/ImServerListenerAdapter.java
@@ -1,35 +1,30 @@
package org.jim.server.listener;
-import org.apache.log4j.Logger;
+import org.jim.common.ImChannelContext;
import org.jim.common.ImConst;
-import org.jim.common.ImConfig;
-import org.jim.common.ImSessionContext;
-import org.jim.common.message.MessageHelper;
-import org.jim.common.packets.Client;
-import org.jim.common.packets.User;
+import org.jim.common.ImPacket;
+import org.jim.server.ImServerChannelContext;
+import org.jim.server.command.handler.processor.chat.MsgQueueRunnable;
+import org.jim.server.config.ImServerConfig;
import org.tio.core.ChannelContext;
import org.tio.core.intf.Packet;
import org.tio.server.intf.ServerAioListener;
-
/**
- *
- * @author WChao
+ *
+ * @author WChao
*
*/
-public class ImServerAioListener implements ServerAioListener {
+public class ImServerListenerAdapter implements ServerAioListener, ImConst{
+
+ private ImServerListener imServerListener;
- Logger logger = Logger.getLogger(ImServerAioListener.class);
-
- private ImConfig imConfig;
-
/**
* @author: WChao
* 2016年12月16日 下午5:52:06
*
*/
- public ImServerAioListener() {}
- public ImServerAioListener(ImConfig imConfig) {
- this.imConfig = imConfig;
+ public ImServerListenerAdapter(ImServerListener imServerListener) {
+ this.imServerListener = imServerListener == null ? new DefaultImServerListener(): imServerListener;
}
/**
*
@@ -41,8 +36,11 @@ public class ImServerAioListener implements ServerAioListener {
* @author: WChao
*/
@Override
- public void onAfterConnected(ChannelContext channelContext, boolean isConnected, boolean isReconnect) {
- return;
+ public void onAfterConnected(ChannelContext channelContext, boolean isConnected, boolean isReconnect)throws Exception{
+ ImServerChannelContext imChannelContext = new ImServerChannelContext(ImServerConfig.Global.get(),channelContext);
+ channelContext.set(Key.IM_CHANNEL_CONTEXT_KEY, imChannelContext);
+ imChannelContext.setMsgQue(new MsgQueueRunnable(imChannelContext, imChannelContext.getImConfig().getJimExecutor()));
+ imServerListener.onAfterConnected(imChannelContext, isConnected, isReconnect);
}
/**
@@ -54,11 +52,12 @@ public class ImServerAioListener implements ServerAioListener {
* @author WChao
*/
@Override
- public void onAfterSent(ChannelContext channelContext, Packet packet, boolean isSentSuccess) {
+ public void onAfterSent(ChannelContext channelContext, Packet packet, boolean isSentSuccess)throws Exception{
+ imServerListener.onAfterSent((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), (ImPacket)packet, isSentSuccess);
}
/**
* 连接关闭前触发本方法
- * @param channelContext the channelcontext
+ * @param channelContext the channelContext
* @param throwable the throwable 有可能为空
* @param remark the remark 有可能为空
* @param isRemove
@@ -66,8 +65,9 @@ public class ImServerAioListener implements ServerAioListener {
* @throws Exception
*/
@Override
- public void onBeforeClose(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove) {
- if (imConfig == null) {
+ public void onBeforeClose(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove)throws Exception{
+ imServerListener.onBeforeClose((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), throwable, remark, isRemove);
+ /*if (imConfig == null) {
return;
}
MessageHelper messageHelper = imConfig.getMessageHelper();
@@ -85,7 +85,7 @@ public class ImServerAioListener implements ServerAioListener {
return;
}
messageHelper.getBindListener().initUserTerminal(channelContext, onlineUser.getTerminal(), ImConst.OFFLINE);
- }
+ }*/
}
/**
* 解码成功后触发本方法
@@ -97,7 +97,7 @@ public class ImServerAioListener implements ServerAioListener {
*/
@Override
public void onAfterDecoded(ChannelContext channelContext, Packet packet,int packetSize) throws Exception {
-
+ imServerListener.onAfterDecoded((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), (ImPacket)packet, packetSize);
}
/**
* 接收到TCP层传过来的数据后
@@ -107,7 +107,7 @@ public class ImServerAioListener implements ServerAioListener {
*/
@Override
public void onAfterReceivedBytes(ChannelContext channelContext,int receivedBytes) throws Exception {
-
+ imServerListener.onAfterReceivedBytes((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), receivedBytes);
}
/**
* 处理一个消息包后
@@ -118,7 +118,11 @@ public class ImServerAioListener implements ServerAioListener {
*/
@Override
public void onAfterHandled(ChannelContext channelContext, Packet packet,long cost) throws Exception {
-
+ imServerListener.onAfterHandled((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), (ImPacket)packet, cost);
}
+ @Override
+ public boolean onHeartbeatTimeout(ChannelContext channelContext, Long aLong, int i) {
+ return imServerListener.onHeartbeatTimeout((ImChannelContext)channelContext.get(Key.IM_CHANNEL_CONTEXT_KEY), aLong, i);
+ }
}
diff --git a/jim-server/src/main/java/org/jim/server/tcp/TcpProtocolHandler.java b/jim-server/src/main/java/org/jim/server/tcp/TcpProtocolHandler.java
index 9fb2813..ed0146e 100644
--- a/jim-server/src/main/java/org/jim/server/tcp/TcpProtocolHandler.java
+++ b/jim-server/src/main/java/org/jim/server/tcp/TcpProtocolHandler.java
@@ -4,26 +4,23 @@
package org.jim.server.tcp;
import org.apache.log4j.Logger;
-import org.jim.common.ImAio;
-import org.jim.common.ImConfig;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.common.exception.ImException;
import org.jim.common.packets.Command;
import org.jim.common.packets.RespBody;
-import org.jim.common.protocol.IProtocol;
-import org.jim.common.tcp.TcpPacket;
-import org.jim.common.tcp.TcpProtocol;
-import org.jim.common.tcp.TcpServerDecoder;
-import org.jim.common.tcp.TcpServerEncoder;
+import org.jim.common.protocol.AbstractProtocol;
+import org.jim.common.tcp.*;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.CommandManager;
+import org.jim.server.config.ImServerConfig;
import org.jim.server.handler.AbstractProtocolHandler;
-import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-import org.tio.core.exception.AioDecodeException;
-import org.tio.core.intf.Packet;
-
import java.nio.ByteBuffer;
+
/**
* 版本: [1.0]
* 功能说明:
@@ -32,40 +29,44 @@ import java.nio.ByteBuffer;
public class TcpProtocolHandler extends AbstractProtocolHandler {
Logger logger = Logger.getLogger(TcpProtocolHandler.class);
-
- @Override
- public void init(ImConfig imConfig) {
+
+ public TcpProtocolHandler(){
+ this.protocol = new TcpProtocol(new TcpConvertPacket());
+ }
+
+ public TcpProtocolHandler(AbstractProtocol protocol){
+ super(protocol);
}
@Override
- public ByteBuffer encode(Packet packet, GroupContext groupContext,ChannelContext channelContext) {
- TcpPacket tcpPacket = (TcpPacket)packet;
- return TcpServerEncoder.encode(tcpPacket, groupContext, channelContext);
+ public void init(ImServerConfig imServerConfig) {
+ logger.info("J-IM TCP协议初始化完毕...");
+ }
+ @Override
+ public ByteBuffer encode(ImPacket imPacket, ImConfig imConfig, ImChannelContext imChannelContext) {
+ TcpPacket tcpPacket = (TcpPacket)imPacket;
+ return TcpServerEncoder.encode(tcpPacket, imConfig, imChannelContext);
}
@Override
- public void handler(Packet packet, ChannelContext channelContext)throws Exception {
+ public void handler(ImPacket packet, ImChannelContext imChannelContext)throws ImException {
TcpPacket tcpPacket = (TcpPacket)packet;
AbstractCmdHandler cmdHandler = CommandManager.getCommand(tcpPacket.getCommand());
if(cmdHandler == null){
ImPacket imPacket = new ImPacket(Command.COMMAND_UNKNOW, new RespBody(Command.COMMAND_UNKNOW,ImStatus.C10017).toByte());
- ImAio.send(channelContext, imPacket);
+ Jim.send(imChannelContext, imPacket);
return;
}
- ImPacket response = cmdHandler.handler(tcpPacket, channelContext);
+ ImPacket response = cmdHandler.handler(tcpPacket, imChannelContext);
if(response != null && tcpPacket.getSynSeq() < 1){
- ImAio.send(channelContext,response);
+ Jim.send(imChannelContext, response);
}
}
@Override
- public TcpPacket decode(ByteBuffer buffer, ChannelContext channelContext)throws AioDecodeException {
- TcpPacket tcpPacket = TcpServerDecoder.decode(buffer, channelContext);
+ public TcpPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ImChannelContext imChannelContext)throws ImDecodeException {
+ TcpPacket tcpPacket = TcpServerDecoder.decode(buffer, imChannelContext);
return tcpPacket;
}
- @Override
- public IProtocol protocol() {
- return new TcpProtocol();
- }
}
diff --git a/jim-server/src/main/java/org/jim/server/util/HttpResps.java b/jim-server/src/main/java/org/jim/server/util/HttpResps.java
index de0ade9..ee9660e 100644
--- a/jim-server/src/main/java/org/jim/server/util/HttpResps.java
+++ b/jim-server/src/main/java/org/jim/server/util/HttpResps.java
@@ -8,6 +8,7 @@ import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
+import org.jim.common.ImConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.jim.common.http.HttpConfig;
@@ -24,7 +25,7 @@ import cn.hutool.core.io.FileUtil;
* @author WChao
* 2017年6月29日 下午4:17:24
*/
-public class HttpResps {
+public class HttpResps implements ImConst.Http {
private static Logger log = LoggerFactory.getLogger(HttpResps.class);
/**
@@ -92,7 +93,7 @@ public class HttpResps {
String filename = fileOnServer.getName();
String extension = FilenameUtils.getExtension(filename);
ret = file(request, bodyBytes, extension);
- ret.addHeader(HttpConst.ResponseHeaderKey.Last_Modified, lastModified.getTime() + "");
+ ret.addHeader(ResponseHeaderKey.Last_Modified, lastModified.getTime() + "");
return ret;
}
@@ -107,7 +108,7 @@ public class HttpResps {
public static HttpResponse fileWithContentType(HttpRequest request, byte[] bodyBytes, String contentType) {
HttpResponse ret = new HttpResponse(request, HttpServerUtils.getHttpConfig(request));
ret.setBodyAndGzip(bodyBytes, request);
- ret.addHeader(HttpConst.ResponseHeaderKey.Content_Type, contentType);
+ ret.addHeader(ResponseHeaderKey.Content_Type, contentType);
return ret;
}
@@ -227,7 +228,7 @@ public class HttpResps {
public static HttpResponse redirect(HttpRequest request, String path) {
HttpResponse ret = new HttpResponse(request, HttpServerUtils.getHttpConfig(request));
ret.setStatus(HttpResponseStatus.C302);
- ret.addHeader(HttpConst.ResponseHeaderKey.Location, path);
+ ret.addHeader(ResponseHeaderKey.Location, path);
return ret;
}
@@ -261,7 +262,7 @@ public class HttpResps {
log.error(e.toString(), e);
}
}
- ret.addHeader(HttpConst.ResponseHeaderKey.Content_Type, Content_Type);
+ ret.addHeader(ResponseHeaderKey.Content_Type, Content_Type);
return ret;
}
@@ -273,7 +274,8 @@ public class HttpResps {
* @author WChao
*/
public static HttpResponse try304(HttpRequest request, long lastModifiedOnServer) {
- String If_Modified_Since = request.getHeader(HttpConst.RequestHeaderKey.If_Modified_Since);//If-Modified-Since
+ //If-Modified-Since
+ String If_Modified_Since = request.getHeader(RequestHeaderKey.If_Modified_Since);
if (StringUtils.isNoneBlank(If_Modified_Since)) {
Long If_Modified_Since_Date = null;
try {
@@ -285,7 +287,7 @@ public class HttpResps {
return ret;
}
} catch (NumberFormatException e) {
- log.warn("{}, {}不是整数,浏览器信息:{}", request.getRemote(), If_Modified_Since, request.getHeader(HttpConst.RequestHeaderKey.User_Agent));
+ log.warn("{}, {}不是整数,浏览器信息:{}", request.getRemote(), If_Modified_Since, request.getHeader(RequestHeaderKey.User_Agent));
return null;
}
}
diff --git a/jim-server/src/main/java/org/jim/server/util/HttpServerUtils.java b/jim-server/src/main/java/org/jim/server/util/HttpServerUtils.java
index 5c5850f..f4b8ceb 100644
--- a/jim-server/src/main/java/org/jim/server/util/HttpServerUtils.java
+++ b/jim-server/src/main/java/org/jim/server/util/HttpServerUtils.java
@@ -1,7 +1,8 @@
package org.jim.server.util;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImSessionContext;
+import org.jim.server.config.ImServerConfig;
import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-import org.jim.common.http.GroupContextKey;
import org.jim.common.http.HttpConfig;
import org.jim.common.http.HttpRequest;
/**
@@ -16,10 +17,8 @@ public class HttpServerUtils {
* @author WChao
*/
public static HttpConfig getHttpConfig(HttpRequest request) {
- ChannelContext channelContext = request.getChannelContext();
- GroupContext groupContext = channelContext.getGroupContext();
- HttpConfig httpConfig = (HttpConfig) groupContext.getAttribute(GroupContextKey.HTTP_SERVER_CONFIG);
- return httpConfig;
+ ImServerConfig imServerConfig = (ImServerConfig)request.getImChannelContext().getImConfig();
+ return imServerConfig.getHttpConfig();
}
/**
diff --git a/jim-server/src/main/java/org/jim/server/ws/WsMsgHandler.java b/jim-server/src/main/java/org/jim/server/ws/WsMsgHandler.java
index 0195cba..feb52fc 100644
--- a/jim-server/src/main/java/org/jim/server/ws/WsMsgHandler.java
+++ b/jim-server/src/main/java/org/jim/server/ws/WsMsgHandler.java
@@ -1,6 +1,8 @@
package org.jim.server.ws;
-import org.jim.common.ImAio;
+import org.jim.common.ImChannelContext;
+import org.jim.common.ImConst;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.http.HttpConst;
import org.jim.common.packets.ChatBody;
@@ -9,11 +11,12 @@ import org.jim.common.ws.IWsMsgHandler;
import org.jim.common.ws.Opcode;
import org.jim.common.ws.WsRequestPacket;
import org.jim.common.ws.WsResponsePacket;
-import org.jim.common.ws.WsServerConfig;
+import org.jim.common.ws.WsConfig;
+import org.jim.server.handler.ProtocolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.Aio;
import org.tio.core.ChannelContext;
+import org.tio.core.Tio;
import java.nio.ByteBuffer;
/**
@@ -23,40 +26,40 @@ import java.nio.ByteBuffer;
public class WsMsgHandler implements IWsMsgHandler{
private static Logger log = LoggerFactory.getLogger(WsMsgHandler.class);
- private WsServerConfig wsServerConfig = null;
+ private WsConfig wsServerConfig = null;
/**
*
* @param text
- * @param channelContext
+ * @param imChannelContext
* @return 可以是WsResponsePacket、String、null
* @author: WChao
*/
@Override
- public Object onText(WsRequestPacket wsRequestPacket, String text, ChannelContext channelContext) throws Exception {
- ChatBody chatBody = ChatKit.toChatBody(wsRequestPacket.getBody(), channelContext);
+ public Object onText(WsRequestPacket wsRequestPacket, String text, ImChannelContext imChannelContext) throws Exception {
+ ChatBody chatBody = ChatKit.toChatBody(wsRequestPacket.getBody(), imChannelContext);
String toId = chatBody.getTo();
- if(ChatKit.isOnline(toId,wsServerConfig)){
- ImAio.sendToUser(toId, wsRequestPacket);
- ImPacket sendSuccessPacket = ChatKit.sendSuccessRespPacket(channelContext);
- text = new String(sendSuccessPacket.getBody(),HttpConst.CHARSET_NAME);
+ if(ChatKit.isOnline(toId,null)){
+ Jim.sendToUser(toId, wsRequestPacket);
+ ImPacket sendSuccessPacket = ProtocolManager.Packet.success(imChannelContext);
+ text = new String(sendSuccessPacket.getBody(), ImConst.Http.CHARSET_NAME);
}else{
- ImPacket offlineRespPacket = ChatKit.offlineRespPacket(channelContext);
- text = new String(offlineRespPacket.getBody(),HttpConst.CHARSET_NAME);
+ ImPacket offlineRespPacket = ProtocolManager.Packet.offline(imChannelContext);
+ text = new String(offlineRespPacket.getBody(), ImConst.Http.CHARSET_NAME);
}
return text;
}
/**
*
- * @param websocketPacket
+ * @param webSocketPacket
* @param bytes
- * @param channelContext
+ * @param imChannelContext
* @return 可以是WsResponsePacket、byte[]、ByteBuffer、null
* @author: WChao
*/
@Override
- public Object onBytes(WsRequestPacket websocketPacket, byte[] bytes, ChannelContext channelContext) throws Exception {
+ public Object onBytes(WsRequestPacket webSocketPacket, byte[] bytes, ImChannelContext imChannelContext) throws Exception {
String text = new String(bytes, "utf-8");
log.info("收到byte消息:{},{}", bytes, text);
ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
@@ -65,54 +68,54 @@ public class WsMsgHandler implements IWsMsgHandler{
}
/**
- * @param channelContext
+ * @param imChannelContext
* @return
* @throws Exception
* @author: WChao
*/
@Override
- public WsResponsePacket handler(ImPacket imPacket, ChannelContext channelContext)throws Exception {
+ public WsResponsePacket handler(ImPacket imPacket, ImChannelContext imChannelContext)throws Exception {
WsRequestPacket wsRequest = (WsRequestPacket)imPacket;
- return h(wsRequest, wsRequest.getBody(), wsRequest.getWsOpcode(), channelContext);
+ return h(wsRequest, wsRequest.getBody(), wsRequest.getWsOpcode(), imChannelContext);
}
- public WsResponsePacket h(WsRequestPacket wsRequest, byte[] bytes, Opcode opcode, ChannelContext channelContext) throws Exception {
+ public WsResponsePacket h(WsRequestPacket wsRequest, byte[] bytes, Opcode opcode, ImChannelContext imChannelContext) throws Exception {
WsResponsePacket wsResponse = null;
if (opcode == Opcode.TEXT) {
if (bytes == null || bytes.length == 0) {
- Aio.remove(channelContext, "错误的websocket包,body为空");
+ Jim.remove(imChannelContext, "错误的webSocket包,body为空");
return null;
}
String text = new String(bytes, wsServerConfig.getCharset());
- Object retObj = this.onText(wsRequest, text, channelContext);
+ Object retObj = this.onText(wsRequest, text, imChannelContext);
String methodName = "onText";
- wsResponse = processRetObj(retObj, methodName, channelContext);
+ wsResponse = processRetObj(retObj, methodName, imChannelContext);
return wsResponse;
} else if (opcode == Opcode.BINARY) {
if (bytes == null || bytes.length == 0) {
- Aio.remove(channelContext, "错误的websocket包,body为空");
+ Jim.remove(imChannelContext, "错误的webSocket包,body为空");
return null;
}
- Object retObj = this.onBytes(wsRequest, bytes, channelContext);
+ Object retObj = this.onBytes(wsRequest, bytes, imChannelContext);
String methodName = "onBytes";
- wsResponse = processRetObj(retObj, methodName, channelContext);
+ wsResponse = processRetObj(retObj, methodName, imChannelContext);
return wsResponse;
} else if (opcode == Opcode.PING || opcode == Opcode.PONG) {
log.error("收到" + opcode);
return null;
} else if (opcode == Opcode.CLOSE) {
- Object retObj = this.onClose(wsRequest, bytes, channelContext);
+ Object retObj = this.onClose(wsRequest, bytes, imChannelContext);
String methodName = "onClose";
- wsResponse = processRetObj(retObj, methodName, channelContext);
+ wsResponse = processRetObj(retObj, methodName, imChannelContext);
return wsResponse;
} else {
- Aio.remove(channelContext, "错误的websocket包,错误的Opcode");
+ Jim.remove(imChannelContext, "错误的webSocket包,错误的Opcode");
return null;
}
}
- private WsResponsePacket processRetObj(Object obj, String methodName, ChannelContext channelContext) throws Exception {
- WsResponsePacket wsResponse = null;
+ private WsResponsePacket processRetObj(Object obj, String methodName, ImChannelContext imChannelContext) throws Exception {
+ WsResponsePacket wsResponse;
if (obj == null) {
return null;
} else {
@@ -136,15 +139,15 @@ public class WsMsgHandler implements IWsMsgHandler{
wsResponse.setWsOpcode(Opcode.BINARY);
return wsResponse;
} else {
- log.error("{} {}.{}()方法,只允许返回byte[]、ByteBuffer、WebSocketResponsePacket或null,但是程序返回了{}", channelContext, this.getClass().getName(), methodName, obj.getClass().getName());
+ log.error("{} {}.{}()方法,只允许返回byte[]、ByteBuffer、WebSocketResponsePacket或null,但是程序返回了{}", imChannelContext, this.getClass().getName(), methodName, obj.getClass().getName());
return null;
}
}
}
@Override
- public Object onClose(WsRequestPacket websocketPacket, byte[] bytes, ChannelContext channelContext) throws Exception {
- Aio.remove(channelContext, "receive close flag");
+ public Object onClose(WsRequestPacket webSocketPacket, byte[] bytes, ImChannelContext imChannelContext) throws Exception {
+ Jim.remove(imChannelContext, "receive close flag");
return null;
}
@@ -152,25 +155,25 @@ public class WsMsgHandler implements IWsMsgHandler{
*
* @author: WChao
*/
- public WsMsgHandler(WsServerConfig wsServerConfig, String[] scanPackages) {
+ public WsMsgHandler(WsConfig wsServerConfig, String[] scanPackages) {
this.setWsServerConfig(wsServerConfig);
//this.routes = new Routes(scanPackages);
}
public WsMsgHandler() {
- this(new WsServerConfig(0), null);
+ this(WsConfig.newBuilder().build(), null);
}
/**
* @return the wsServerConfig
*/
- public WsServerConfig getWsServerConfig() {
+ public WsConfig getWsServerConfig() {
return wsServerConfig;
}
/**
* @param wsServerConfig the wsServerConfig to set
*/
- public void setWsServerConfig(WsServerConfig wsServerConfig) {
+ public void setWsServerConfig(WsConfig wsServerConfig) {
this.wsServerConfig = wsServerConfig;
}
diff --git a/jim-server/src/main/java/org/jim/server/ws/WsProtocolHandler.java b/jim-server/src/main/java/org/jim/server/ws/WsProtocolHandler.java
index 80be588..6590b5b 100644
--- a/jim-server/src/main/java/org/jim/server/ws/WsProtocolHandler.java
+++ b/jim-server/src/main/java/org/jim/server/ws/WsProtocolHandler.java
@@ -3,10 +3,13 @@
*/
package org.jim.server.ws;
-import org.jim.common.ImAio;
-import org.jim.common.ImConfig;
+import org.jim.common.ImChannelContext;
+import org.jim.common.Jim;
import org.jim.common.ImPacket;
import org.jim.common.ImStatus;
+import org.jim.common.config.ImConfig;
+import org.jim.common.exception.ImDecodeException;
+import org.jim.common.exception.ImException;
import org.jim.common.http.HttpRequest;
import org.jim.common.http.HttpRequestDecoder;
import org.jim.common.http.HttpResponse;
@@ -14,108 +17,101 @@ import org.jim.common.http.HttpResponseEncoder;
import org.jim.common.packets.Command;
import org.jim.common.packets.Message;
import org.jim.common.packets.RespBody;
-import org.jim.common.protocol.IProtocol;
+import org.jim.common.protocol.AbstractProtocol;
import org.jim.common.utils.JsonKit;
-import org.jim.common.ws.IWsMsgHandler;
-import org.jim.common.ws.Opcode;
-import org.jim.common.ws.WsProtocol;
-import org.jim.common.ws.WsRequestPacket;
-import org.jim.common.ws.WsResponsePacket;
-import org.jim.common.ws.WsServerConfig;
-import org.jim.common.ws.WsServerDecoder;
-import org.jim.common.ws.WsServerEncoder;
-import org.jim.common.ws.WsSessionContext;
+import org.jim.common.ws.*;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.CommandManager;
+import org.jim.server.config.ImServerConfig;
import org.jim.server.handler.AbstractProtocolHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.tio.core.ChannelContext;
-import org.tio.core.GroupContext;
-import org.tio.core.exception.AioDecodeException;
-import org.tio.core.intf.Packet;
import java.nio.ByteBuffer;
+import java.util.Objects;
+
/**
* 版本: [1.0]
* 功能说明:
- * 作者: WChao 创建时间: 2017年8月3日 下午6:38:36
+ * @author : WChao 创建时间: 2017年8月3日 下午6:38:36
*/
public class WsProtocolHandler extends AbstractProtocolHandler {
private Logger logger = LoggerFactory.getLogger(WsProtocolHandler.class);
- private WsServerConfig wsServerConfig;
+ private WsConfig wsServerConfig;
private IWsMsgHandler wsMsgHandler;
- public WsProtocolHandler() {}
+ public WsProtocolHandler() {
+ this.protocol = new WsProtocol(new WsConvertPacket());
+ }
- public WsProtocolHandler(WsServerConfig wsServerConfig, IWsMsgHandler wsMsgHandler) {
+ public WsProtocolHandler(WsConfig wsServerConfig, AbstractProtocol protocol) {
+ super(protocol);
this.wsServerConfig = wsServerConfig;
- this.wsMsgHandler = wsMsgHandler;
}
@Override
- public void init(ImConfig imConfig) {
- WsServerConfig wsServerConfig = imConfig.getWsServerConfig();
- if(wsServerConfig == null){
- wsServerConfig = new WsServerConfig();
- imConfig.setWsServerConfig(wsServerConfig);
+ public void init(ImServerConfig imServerConfig) {
+ WsConfig wsConfig = imServerConfig.getWsConfig();
+ if(Objects.isNull(wsConfig)){
+ wsConfig = WsConfig.newBuilder().build();
+ imServerConfig.setWsConfig(wsConfig);
}
- IWsMsgHandler wsMsgHandler = wsServerConfig.getWsMsgHandler();
- if(wsMsgHandler == null){
- wsServerConfig.setWsMsgHandler(new WsMsgHandler());
+ IWsMsgHandler wsMsgHandler = wsConfig.getWsMsgHandler();
+ if(Objects.isNull(wsMsgHandler)){
+ wsConfig.setWsMsgHandler(new WsMsgHandler());
}
- this.wsServerConfig = wsServerConfig;
+ this.wsServerConfig = wsConfig;
this.wsMsgHandler = wsServerConfig.getWsMsgHandler();
- logger.info("wsServerHandler 初始化完毕...");
+ logger.info("J-IM WebSocket协议初始化完毕...");
}
@Override
- public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
- WsSessionContext wsSessionContext = (WsSessionContext)channelContext.getAttribute();
- WsResponsePacket wsResponsePacket = (WsResponsePacket)packet;
+ public ByteBuffer encode(ImPacket imPacket, ImConfig imConfig, ImChannelContext imChannelContext) {
+ WsSessionContext wsSessionContext = (WsSessionContext)imChannelContext.getSessionContext();
+ WsResponsePacket wsResponsePacket = (WsResponsePacket)imPacket;
if (wsResponsePacket.getCommand() == Command.COMMAND_HANDSHAKE_RESP) {
//握手包
HttpResponse handshakeResponsePacket = wsSessionContext.getHandshakeResponsePacket();
- return HttpResponseEncoder.encode(handshakeResponsePacket, groupContext, channelContext,true);
+ return HttpResponseEncoder.encode(handshakeResponsePacket, imChannelContext,true);
}else{
- return WsServerEncoder.encode(wsResponsePacket , groupContext, channelContext);
+ return WsServerEncoder.encode(wsResponsePacket , imChannelContext);
}
}
@Override
- public void handler(Packet packet, ChannelContext channelContext) throws Exception {
- WsRequestPacket wsRequestPacket = (WsRequestPacket) packet;
+ public void handler(ImPacket imPacket, ImChannelContext imChannelContext) throws ImException {
+ WsRequestPacket wsRequestPacket = (WsRequestPacket) imPacket;
AbstractCmdHandler cmdHandler = CommandManager.getCommand(wsRequestPacket.getCommand());
if(cmdHandler == null){
//是否ws分片发包尾帧包
if(!wsRequestPacket.isWsEof()) {
return;
}
- ImPacket imPacket = new ImPacket(Command.COMMAND_UNKNOW, new RespBody(Command.COMMAND_UNKNOW,ImStatus.C10017).toByte());
- ImAio.send(channelContext, imPacket);
+ ImPacket wsPacket = new ImPacket(Command.COMMAND_UNKNOW, new RespBody(Command.COMMAND_UNKNOW,ImStatus.C10017).toByte());
+ Jim.send(imChannelContext, wsPacket);
return;
}
- ImPacket response = cmdHandler.handler(wsRequestPacket, channelContext);
+ ImPacket response = cmdHandler.handler(wsRequestPacket, imChannelContext);
if(response != null){
- ImAio.send(channelContext, response);
+ Jim.send(imChannelContext, response);
}
}
@Override
- public ImPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException {
- WsSessionContext wsSessionContext = (WsSessionContext)channelContext.getAttribute();
+ public ImPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ImChannelContext imChannelContext) throws ImDecodeException {
+ WsSessionContext wsSessionContext = (WsSessionContext)imChannelContext.getSessionContext();
//握手
if(!wsSessionContext.isHandshaked()){
- HttpRequest httpRequest = HttpRequestDecoder.decode(buffer,channelContext,true);
+ HttpRequest httpRequest = HttpRequestDecoder.decode(buffer,imChannelContext,true);
if(httpRequest == null) {
return null;
}
//升级到WebSocket协议处理
- HttpResponse httpResponse = WsServerDecoder.updateWebSocketProtocol(httpRequest,channelContext);
+ HttpResponse httpResponse = WsServerDecoder.updateWebSocketProtocol(httpRequest, imChannelContext);
if (httpResponse == null) {
- throw new AioDecodeException("http协议升级到websocket协议失败");
+ throw new ImDecodeException("http协议升级到webSocket协议失败");
}
wsSessionContext.setHandshakeRequestPacket(httpRequest);
wsSessionContext.setHandshakeResponsePacket(httpResponse);
@@ -125,7 +121,7 @@ public class WsProtocolHandler extends AbstractProtocolHandler {
wsRequestPacket.setCommand(Command.COMMAND_HANDSHAKE_REQ);
return wsRequestPacket;
}else{
- WsRequestPacket wsRequestPacket = WsServerDecoder.decode(buffer, channelContext);
+ WsRequestPacket wsRequestPacket = WsServerDecoder.decode(buffer, imChannelContext);
if(wsRequestPacket == null) {
return null;
}
@@ -144,11 +140,11 @@ public class WsProtocolHandler extends AbstractProtocolHandler {
return wsRequestPacket;
}
}
- public WsServerConfig getWsServerConfig() {
+ public WsConfig getWsServerConfig() {
return wsServerConfig;
}
- public void setWsServerConfig(WsServerConfig wsServerConfig) {
+ public void setWsServerConfig(WsConfig wsServerConfig) {
this.wsServerConfig = wsServerConfig;
}
@@ -160,8 +156,4 @@ public class WsProtocolHandler extends AbstractProtocolHandler {
this.wsMsgHandler = wsMsgHandler;
}
- @Override
- public IProtocol protocol() {
- return new WsProtocol();
- }
}