mirror of
https://gitee.com/xchao/j-im.git
synced 2024-12-03 12:27:35 +08:00
优化代码规范
This commit is contained in:
parent
f18fae7026
commit
da7f2af79d
@ -24,7 +24,7 @@ import org.tio.utils.lock.SetWithLock;
|
||||
/**
|
||||
* 版本: [1.0]
|
||||
* 功能说明:
|
||||
* 作者: WChao 创建时间: 2017年9月22日 上午9:07:18
|
||||
* @author : WChao 创建时间: 2017年9月22日 上午9:07:18
|
||||
*/
|
||||
public class ImAio {
|
||||
|
||||
@ -33,21 +33,23 @@ public class ImAio {
|
||||
private static Logger log = LoggerFactory.getLogger(ImAio.class);
|
||||
/**
|
||||
* 功能描述:[根据用户ID获取当前用户]
|
||||
* 创建者:WChao 创建时间: 2017年9月18日 下午4:34:39
|
||||
* @author:WChao 创建时间: 2017年9月18日 下午4:34:39
|
||||
* @param groupContext
|
||||
* @param userid
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static User getUser(String userid){
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserid(userid);
|
||||
if(userChannelContexts == null)
|
||||
public static User getUser(String userId){
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserId(userId);
|
||||
if(userChannelContexts == null) {
|
||||
return null;
|
||||
}
|
||||
ReadLock readLock = userChannelContexts.getLock().readLock();
|
||||
readLock.lock();
|
||||
try{
|
||||
Set<ChannelContext> userChannels = userChannelContexts.getObj();
|
||||
if(userChannels == null )
|
||||
if(userChannels == null ) {
|
||||
return null;
|
||||
}
|
||||
User user = null;
|
||||
for(ChannelContext channelContext : userChannels){
|
||||
ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
|
||||
@ -63,37 +65,35 @@ public class ImAio {
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* 功能描述:[根据用户ID获取当前用户所在通道集合]
|
||||
* 创建者:WChao 创建时间: 2017年9月18日 下午4:34:39
|
||||
* @param groupContext
|
||||
* @param userid
|
||||
* @return
|
||||
*
|
||||
* 功能描述:[根据用户ID获取当前用户所在通道集合]
|
||||
* @author:WChao 创建时间: 2017年9月18日 下午4:34:39
|
||||
* @param groupContext
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public static SetWithLock<ChannelContext> getChannelContextsByUserid(String userid){
|
||||
SetWithLock<ChannelContext> channelContexts = Aio.getChannelContextsByUserid(imConfig.getGroupContext(), userid);
|
||||
public static SetWithLock<ChannelContext> getChannelContextsByUserId(String userId){
|
||||
SetWithLock<ChannelContext> channelContexts = Aio.getChannelContextsByUserid(imConfig.getGroupContext(), userId);
|
||||
return channelContexts;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* 功能描述:[获取所有用户(在线+离线)]
|
||||
* 创建者:WChao 创建时间: 2017年9月18日 下午4:31:54
|
||||
* @param groupContext
|
||||
* @return
|
||||
*
|
||||
* 功能描述:[获取所有用户(在线+离线)]
|
||||
* @author:WChao 创建时间: 2017年9月18日 下午4:31:54
|
||||
* @param groupContext
|
||||
* @return
|
||||
*/
|
||||
public static List<User> getAllUser(){
|
||||
List<User> users = new ArrayList<User>();
|
||||
SetWithLock<ChannelContext> allChannels = Aio.getAllChannelContexts(imConfig.getGroupContext());
|
||||
if(allChannels == null)
|
||||
if(allChannels == null) {
|
||||
return users;
|
||||
}
|
||||
ReadLock readLock = allChannels.getLock().readLock();
|
||||
readLock.lock();
|
||||
try{
|
||||
Set<ChannelContext> userChannels = allChannels.getObj();
|
||||
if(userChannels == null)
|
||||
if(userChannels == null) {
|
||||
return users;
|
||||
}
|
||||
for(ChannelContext channelContext : userChannels){
|
||||
ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
|
||||
Client client = imSessionContext.getClient();
|
||||
@ -108,18 +108,17 @@ public class ImAio {
|
||||
return users;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* 功能描述:[获取所有在线用户]
|
||||
* 创建者:WChao 创建时间: 2017年9月18日 下午4:31:42
|
||||
* @param groupContext
|
||||
* @return
|
||||
*
|
||||
* 功能描述:[获取所有在线用户]
|
||||
* @author:WChao 创建时间: 2017年9月18日 下午4:31:42
|
||||
* @param groupContext
|
||||
* @return
|
||||
*/
|
||||
public static List<User> getAllOnlineUser(){
|
||||
List<User> users = new ArrayList<User>();
|
||||
SetWithLock<ChannelContext> onlineChannels = Aio.getAllConnectedsChannelContexts(imConfig.getGroupContext());
|
||||
if(onlineChannels == null)
|
||||
if(onlineChannels == null) {
|
||||
return users;
|
||||
}
|
||||
ReadLock readLock = onlineChannels.getLock().readLock();
|
||||
readLock.lock();
|
||||
try{
|
||||
@ -157,11 +156,11 @@ public class ImAio {
|
||||
List<User> users = new ArrayList<User>();
|
||||
Map<String,User> userMaps = new HashMap<String,User>();
|
||||
for(ChannelContext channelContext : channels){
|
||||
String userid = channelContext.getUserid();
|
||||
User user = getUser(userid);
|
||||
String userId = channelContext.getUserid();
|
||||
User user = getUser(userId);
|
||||
if(user != null){
|
||||
if(userMaps.get(userid) == null){
|
||||
userMaps.put(userid, user);
|
||||
if(userMaps.get(userId) == null){
|
||||
userMaps.put(userId, user);
|
||||
users.add(user);
|
||||
}
|
||||
}
|
||||
@ -176,14 +175,15 @@ public class ImAio {
|
||||
}
|
||||
/**
|
||||
* 功能描述:[发送到群组(所有不同协议端)]
|
||||
* 创建者:WChao 创建时间: 2017年9月21日 下午3:26:57
|
||||
* @author:WChao 创建时间: 2017年9月21日 下午3:26:57
|
||||
* @param groupContext
|
||||
* @param group
|
||||
* @param packet
|
||||
*/
|
||||
public static void sendToGroup(String group, ImPacket packet){
|
||||
if(packet.getBody() == null)
|
||||
if(packet.getBody() == null) {
|
||||
return;
|
||||
}
|
||||
SetWithLock<ChannelContext> withLockChannels = Aio.getChannelContextsByGroup(imConfig.getGroupContext(), group);
|
||||
if(withLockChannels == null){
|
||||
ImCluster cluster = imConfig.getCluster();
|
||||
@ -241,9 +241,10 @@ public class ImAio {
|
||||
* @param packet
|
||||
*/
|
||||
public static void sendToUser(String userId,ImPacket packet){
|
||||
if(StringUtils.isEmpty(userId))
|
||||
if(StringUtils.isEmpty(userId)) {
|
||||
return;
|
||||
SetWithLock<ChannelContext> toChannelContexts = getChannelContextsByUserid(userId);
|
||||
}
|
||||
SetWithLock<ChannelContext> toChannelContexts = getChannelContextsByUserId(userId);
|
||||
if(toChannelContexts == null || toChannelContexts.size() < 1){
|
||||
ImCluster cluster = imConfig.getCluster();
|
||||
if (cluster != null && !packet.isFromCluster()) {
|
||||
@ -271,11 +272,11 @@ public class ImAio {
|
||||
* @param groupContext
|
||||
* @param ip
|
||||
* @param packet
|
||||
* @author: WChao
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@ -321,8 +322,9 @@ public class ImAio {
|
||||
* @return
|
||||
*/
|
||||
private static ImPacket initAndSetConvertPacket(ChannelContext channelContext , ImPacket packet){
|
||||
if(channelContext == null)
|
||||
if(channelContext == null) {
|
||||
return null;
|
||||
}
|
||||
ImPacket respPacket = ImKit.ConvertRespPacket(packet,packet.getCommand(),channelContext);
|
||||
if(respPacket == null){
|
||||
log.error("转换协议包为空,请检查协议!");
|
||||
@ -337,22 +339,22 @@ public class ImAio {
|
||||
/**
|
||||
* 绑定用户;
|
||||
* @param channelContext
|
||||
* @param userid
|
||||
* @param userId
|
||||
*/
|
||||
public static void bindUser(ChannelContext channelContext,String userid){
|
||||
bindUser(channelContext, userid,null);
|
||||
public static void bindUser(ChannelContext channelContext,String userId){
|
||||
bindUser(channelContext, userId,null);
|
||||
}
|
||||
/**
|
||||
* 绑定用户,同时可传递监听器执行回调函数
|
||||
* @param channelContext
|
||||
* @param userid
|
||||
* @param userId
|
||||
* @param bindListener(绑定监听器回调)
|
||||
*/
|
||||
public static void bindUser(ChannelContext channelContext,String userid,ImBindListener bindListener){
|
||||
Aio.bindUser(channelContext, userid);
|
||||
public static void bindUser(ChannelContext channelContext,String userId,ImBindListener bindListener){
|
||||
Aio.bindUser(channelContext, userId);
|
||||
if(bindListener != null){
|
||||
try {
|
||||
bindListener.onAfterUserBind(channelContext, userid);
|
||||
bindListener.onAfterUserBind(channelContext, userId);
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
}
|
||||
@ -361,30 +363,31 @@ public class ImAio {
|
||||
/**
|
||||
* 解绑用户
|
||||
* @param groupContext
|
||||
* @param userid
|
||||
* @param userId
|
||||
*/
|
||||
public static void unbindUser(String userid){
|
||||
unbindUser(userid, null);
|
||||
public static void unbindUser(String userId){
|
||||
unbindUser(userId, null);
|
||||
}
|
||||
/**
|
||||
* 解除绑定用户,同时可传递监听器执行回调函数
|
||||
* @param channelContext
|
||||
* @param userid
|
||||
* @param userId
|
||||
* @param bindListener(解绑定监听器回调)
|
||||
*/
|
||||
public static void unbindUser(String userid,ImBindListener bindListener){
|
||||
Aio.unbindUser(imConfig.getGroupContext(), userid);
|
||||
public static void unbindUser(String userId,ImBindListener bindListener){
|
||||
Aio.unbindUser(imConfig.getGroupContext(), userId);
|
||||
if(bindListener != null){
|
||||
try {
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserid(userid);
|
||||
if(userChannelContexts == null || userChannelContexts.size() == 0)
|
||||
return ;
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserId(userId);
|
||||
if(userChannelContexts == null || userChannelContexts.size() == 0) {
|
||||
return;
|
||||
}
|
||||
ReadLock readLock = userChannelContexts.getLock().readLock();
|
||||
readLock.lock();
|
||||
try{
|
||||
Set<ChannelContext> channels = userChannelContexts.getObj();
|
||||
for(ChannelContext channelContext : channels){
|
||||
bindListener.onAfterUserBind(channelContext, userid);
|
||||
bindListener.onAfterUserBind(channelContext, userId);
|
||||
}
|
||||
}finally{
|
||||
readLock.unlock();
|
||||
@ -420,23 +423,24 @@ public class ImAio {
|
||||
}
|
||||
/**
|
||||
* 与指定群组解除绑定
|
||||
* @param userid
|
||||
* @param userId
|
||||
* @param group
|
||||
* @param bindListener
|
||||
*/
|
||||
public static void unbindGroup(String userid,String group){
|
||||
unbindGroup(userid, group, null);
|
||||
public static void unbindGroup(String userId,String group){
|
||||
unbindGroup(userId, group, null);
|
||||
}
|
||||
/**
|
||||
* 与指定群组解除绑定,同时可传递监听器执行回调函数
|
||||
* @param channelContext
|
||||
* @param userId
|
||||
* @param group
|
||||
* @param binListener(解绑定监听器回调)
|
||||
*/
|
||||
public static void unbindGroup(String userid,String group,ImBindListener bindListener){
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserid(userid);
|
||||
if(userChannelContexts == null || userChannelContexts.size() == 0)
|
||||
return ;
|
||||
public static void unbindGroup(String userId,String group,ImBindListener bindListener){
|
||||
SetWithLock<ChannelContext> userChannelContexts = ImAio.getChannelContextsByUserId(userId);
|
||||
if(userChannelContexts == null || userChannelContexts.size() == 0) {
|
||||
return;
|
||||
}
|
||||
ReadLock readLock = userChannelContexts.getLock().readLock();
|
||||
readLock.lock();
|
||||
try{
|
||||
@ -457,11 +461,11 @@ public class ImAio {
|
||||
}
|
||||
/**
|
||||
* 移除用户, 和close方法一样,只不过不再进行重连等维护性的操作
|
||||
* @param userid
|
||||
* @param userId
|
||||
* @param remark
|
||||
*/
|
||||
public static void remove(String userid,String remark){
|
||||
SetWithLock<ChannelContext> userChannelContexts = getChannelContextsByUserid(userid);
|
||||
public static void remove(String userId,String remark){
|
||||
SetWithLock<ChannelContext> userChannelContexts = getChannelContextsByUserId(userId);
|
||||
if(userChannelContexts != null && userChannelContexts.size() > 0){
|
||||
ReadLock readLock = userChannelContexts.getLock().readLock();
|
||||
readLock.lock();
|
||||
@ -477,7 +481,7 @@ public class ImAio {
|
||||
}
|
||||
/**
|
||||
* 移除指定channel, 和close方法一样,只不过不再进行重连等维护性的操作
|
||||
* @param userid
|
||||
* @param channelContext
|
||||
* @param remark
|
||||
*/
|
||||
public static void remove(ChannelContext channelContext,String remark){
|
||||
|
@ -11,12 +11,18 @@ import org.jim.common.packets.Command;
|
||||
public class ImPacket extends Packet
|
||||
{
|
||||
private static final long serialVersionUID = 2000118564569232098L;
|
||||
|
||||
protected Status status;//包状态码;
|
||||
|
||||
protected byte[] body;//消息体;
|
||||
|
||||
private Command command;//消息命令;
|
||||
/**
|
||||
* 包状态码;
|
||||
*/
|
||||
protected Status status;
|
||||
/**
|
||||
* 消息体;
|
||||
*/
|
||||
protected byte[] body;
|
||||
/**
|
||||
* 消息命令;
|
||||
*/
|
||||
private Command command;
|
||||
/**
|
||||
* 消息是否是另外一台机器通过topic转过来的,如果是就不要死循环地再一次转发啦
|
||||
* 这个属性是j-im内部使用,业务层的用户请务使用
|
||||
@ -104,10 +110,7 @@ public class ImPacket extends Packet
|
||||
/**
|
||||
* 计算消息头占用了多少字节数
|
||||
* @return
|
||||
*
|
||||
* @author: wchao
|
||||
* 2017年1月31日 下午5:32:26
|
||||
*
|
||||
*/
|
||||
public int calcHeaderLength(boolean is4byteLength)
|
||||
{
|
||||
@ -150,11 +153,8 @@ public class ImPacket extends Packet
|
||||
|
||||
/**
|
||||
* @see org.tio.core.intf.Packet#logstr()
|
||||
*
|
||||
* @return
|
||||
* @author: wchao
|
||||
* 2017年2月22日 下午3:15:18
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String logstr()
|
||||
@ -170,11 +170,4 @@ public class ImPacket extends Packet
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean isFromCluster() {
|
||||
return isFromCluster;
|
||||
}
|
||||
|
||||
public void setFromCluster(boolean isFromCluster) {
|
||||
this.isFromCluster = isFromCluster;
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ public class ImSessionContext extends SessionContext
|
||||
/**
|
||||
* 消息请求频率控制器
|
||||
*/
|
||||
private RateLimiterWrap requestRateLimiter = null;
|
||||
protected RateLimiterWrap requestRateLimiter = null;
|
||||
|
||||
private Client client = null;
|
||||
protected Client client = null;
|
||||
|
||||
private String token = null;
|
||||
protected String token = null;
|
||||
/**
|
||||
* 通道所属协议处理器;
|
||||
*/
|
||||
|
@ -65,7 +65,7 @@ public class RedisAsyncRunnable implements Runnable{
|
||||
count = 0;
|
||||
}else if(count == 0 && redisL2Vo == null){
|
||||
try {
|
||||
Thread.currentThread().sleep(1000L);
|
||||
Thread.sleep(1000L);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error(e.toString(),e);
|
||||
}
|
||||
|
@ -682,8 +682,9 @@ public class JedisTemplate implements Serializable{
|
||||
* @param pairDatas
|
||||
*/
|
||||
public void batchSetExpire(List<PairEx<String,Void,Integer>> pairDatas){
|
||||
if(pairDatas == null || pairDatas.size() == 0)
|
||||
return;
|
||||
if(pairDatas == null || pairDatas.size() == 0) {
|
||||
return;
|
||||
}
|
||||
new Executor<Void>(jedisPool) {
|
||||
@Override
|
||||
Void execute() {
|
||||
@ -1075,8 +1076,9 @@ public class JedisTemplate implements Serializable{
|
||||
* @param List<message> 要发布的信息
|
||||
*/
|
||||
public void publishAll(final String channel, final List<String> messages) {
|
||||
if(messages == null || messages.size() == 0)
|
||||
return;
|
||||
if(messages == null || messages.size() == 0) {
|
||||
return;
|
||||
}
|
||||
new Executor<Void>(jedisPool) {
|
||||
@Override
|
||||
Void execute() {
|
||||
|
@ -158,8 +158,9 @@ public class RedisCache implements ICache {
|
||||
return null;
|
||||
}
|
||||
public Long listRemove(String key ,String value){
|
||||
if(StringUtils.isBlank(key) || StringUtils.isBlank(value))
|
||||
if(StringUtils.isBlank(key) || StringUtils.isBlank(value)) {
|
||||
return 0L;
|
||||
}
|
||||
try {
|
||||
return JedisTemplate.me().listRemove(cacheKey(cacheName, key), 0, value);
|
||||
} catch (Exception e) {
|
||||
@ -183,10 +184,11 @@ public class RedisCache implements ICache {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Set<String> datas = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),Double.MIN_VALUE,Double.MAX_VALUE);
|
||||
if(datas == null)
|
||||
Set<String> dataSet = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),Double.MIN_VALUE,Double.MAX_VALUE);
|
||||
if(dataSet == null) {
|
||||
return null;
|
||||
return new ArrayList<String>(datas);
|
||||
}
|
||||
return new ArrayList<String>(dataSet);
|
||||
}catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
}
|
||||
@ -197,10 +199,11 @@ public class RedisCache implements ICache {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Set<String> datas = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),min,max);
|
||||
if(datas == null)
|
||||
Set<String> dataSet = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),min,max);
|
||||
if(dataSet == null) {
|
||||
return null;
|
||||
return new ArrayList<String>(datas);
|
||||
}
|
||||
return new ArrayList<String>(dataSet);
|
||||
}catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
}
|
||||
@ -211,10 +214,11 @@ public class RedisCache implements ICache {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Set<String> datas = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),min,max,offset,count);
|
||||
if(datas == null)
|
||||
Set<String> dataSet = JedisTemplate.me().sorSetRangeByScore(cacheKey(cacheName, key),min,max,offset,count);
|
||||
if(dataSet == null) {
|
||||
return null;
|
||||
return new ArrayList<String>(datas);
|
||||
}
|
||||
return new ArrayList<String>(dataSet);
|
||||
}catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
}
|
||||
|
@ -26,8 +26,9 @@ public class RedisConfiguration {
|
||||
this.maxWait = Long.valueOf(prop.getProperty("jim.redis.maxwait","5000"));
|
||||
this.timeout = Integer.valueOf(prop.getProperty("jim.redis.timeout", "2000"));
|
||||
this.auth = prop.getProperty("jim.redis.auth",null);
|
||||
if(StringUtils.isEmpty(auth))
|
||||
if(StringUtils.isEmpty(auth)) {
|
||||
this.auth = null;
|
||||
}
|
||||
this.host = prop.getProperty("jim.redis.host","");
|
||||
this.port = Integer.valueOf(prop.getProperty("jim.redis.port","0"));
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class SubRunnable implements Runnable {
|
||||
}
|
||||
this.subChannel = subChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
log.debug("订阅 redis , chanel {} , 线程将阻塞",subChannel);
|
||||
while(true){
|
||||
|
@ -162,6 +162,11 @@ public class Config {
|
||||
}
|
||||
|
||||
public interface Builder {
|
||||
/**
|
||||
* 配置构建接口
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
Config build() throws Exception;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public abstract class ImConfigBuilder implements Config.Builder {
|
||||
this.conf.bindIp = bindIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public ImConfigBuilder setBindPort(Integer bindPort) {
|
||||
this.conf.bindPort = bindPort;
|
||||
return this;
|
||||
@ -86,8 +86,9 @@ public abstract class ImConfigBuilder implements Config.Builder {
|
||||
this.conf.readBufferSize = readBufferSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ImConfig build() {
|
||||
|
||||
@Override
|
||||
public ImConfig build() {
|
||||
this.configHttp(conf.getHttpConfig());
|
||||
this.configWs(conf.getWsServerConfig());
|
||||
return conf;
|
||||
|
@ -21,12 +21,17 @@ public class PropertyImConfigBuilder extends ImConfigBuilder {
|
||||
|
||||
@Override
|
||||
public ImConfigBuilder configHttp(HttpConfig httpConfig) {
|
||||
String pageRoot = PropKit.get("jim.http.page");//html/css/js等的根目录,支持classpath:,也支持绝对路径
|
||||
String[] scanPackages = PropKit.get("jim.http.scan.packages").split(",");//j-im mvc需要扫描的根目录包
|
||||
//html/css/js等的根目录,支持classpath:,也支持绝对路径
|
||||
String pageRoot = PropKit.get("jim.http.page");
|
||||
//j-im mvc需要扫描的根目录包
|
||||
String[] scanPackages = PropKit.get("jim.http.scan.packages").split(",");
|
||||
httpConfig.setBindPort((PropKit.getInt("jim.port")));
|
||||
httpConfig.setPageRoot(pageRoot);//设置web访问路径;
|
||||
httpConfig.setMaxLiveTimeOfStaticRes(PropKit.getInt("jim.http.max.live.time"));//不缓存资源;
|
||||
httpConfig.setScanPackages(scanPackages);//设置j-im mvc扫描目录;
|
||||
//设置web访问路径;
|
||||
httpConfig.setPageRoot(pageRoot);
|
||||
//不缓存资源;
|
||||
httpConfig.setMaxLiveTimeOfStaticRes(PropKit.getInt("jim.http.max.live.time"));
|
||||
//设置j-im mvc扫描目录;
|
||||
httpConfig.setScanPackages(scanPackages);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -36,7 +41,7 @@ public class PropertyImConfigBuilder extends ImConfigBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ImConfig build() {
|
||||
super.build();
|
||||
this.setBindIp(PropKit.get("jim.bind.ip"));
|
||||
|
@ -57,13 +57,6 @@ public class HttpConfig extends Config{
|
||||
|
||||
}
|
||||
|
||||
private String bindIp = null;//"127.0.0.1";
|
||||
|
||||
/**
|
||||
* 监听端口
|
||||
*/
|
||||
private Integer bindPort = 80;
|
||||
|
||||
private String serverInfo = HttpConst.SERVER_INFO;
|
||||
|
||||
private String charset = HttpConst.CHARSET_NAME;
|
||||
@ -102,8 +95,9 @@ public class HttpConfig extends Config{
|
||||
* 示例:
|
||||
* 1、classpath中:page
|
||||
* 2、绝对路径:/page
|
||||
* //FileUtil.getAbsolutePath("page");//"/page";
|
||||
*/
|
||||
private String pageRoot = null;//FileUtil.getAbsolutePath("page");//"/page";
|
||||
private String pageRoot = null;
|
||||
/**
|
||||
* mvc扫描包路径;
|
||||
*/
|
||||
@ -123,21 +117,6 @@ public class HttpConfig extends Config{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the bindIp
|
||||
*/
|
||||
public String getBindIp() {
|
||||
return bindIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bindPort
|
||||
*/
|
||||
public Integer getBindPort() {
|
||||
return bindPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the charset
|
||||
*/
|
||||
@ -185,10 +164,6 @@ public class HttpConfig extends Config{
|
||||
return sessionCookieName;
|
||||
}
|
||||
|
||||
// public void setSessionTimeout(long sessionTimeout) {
|
||||
// this.sessionTimeout = sessionTimeout;
|
||||
// }
|
||||
|
||||
public ISessionIdGenerator getSessionIdGenerator() {
|
||||
return sessionIdGenerator;
|
||||
}
|
||||
@ -201,13 +176,6 @@ public class HttpConfig extends Config{
|
||||
return sessionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bindIp the bindIp to set
|
||||
*/
|
||||
public void setBindIp(String bindIp) {
|
||||
this.bindIp = bindIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charset the charset to set
|
||||
*/
|
||||
@ -296,8 +264,4 @@ public class HttpConfig extends Config{
|
||||
this.httpServerListener = httpServerListener;
|
||||
}
|
||||
|
||||
public void setBindPort(Integer bindPort) {
|
||||
this.bindPort = bindPort;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ import org.jim.common.utils.ImUtils;
|
||||
import org.tio.core.ChannelContext;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Http协议校验器
|
||||
* @author WChao
|
||||
*
|
||||
*/
|
||||
@ -27,10 +28,11 @@ public class HttpProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtoc(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
|
||||
if(imSessionContext != null && imSessionContext instanceof HttpSession)
|
||||
if(imSessionContext != null && 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)
|
||||
@ -44,14 +46,15 @@ public class HttpProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IConvertProtocolPacket convertor() {
|
||||
public IConvertProtocolPacket converter() {
|
||||
return new HttpConvertPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
|
||||
if(imPacket == null)
|
||||
if(imPacket == null) {
|
||||
return false;
|
||||
}
|
||||
if(imPacket instanceof HttpPacket){
|
||||
Object sessionContext = channelContext.getAttribute();
|
||||
if(sessionContext == null){
|
||||
|
@ -42,16 +42,13 @@ public class HttpRequest extends HttpPacket {
|
||||
private List<Cookie> cookies = null;
|
||||
private Map<String, Cookie> cookieMap = null;
|
||||
private int contentLength;
|
||||
// private byte[] bodyBytes;
|
||||
private String bodyString;
|
||||
// private UserAgent userAgent;
|
||||
private RequestBodyFormat bodyFormat;
|
||||
private String charset = HttpConst.CHARSET_NAME;
|
||||
private Boolean isAjax = null;
|
||||
private Boolean isSupportGzip = null;
|
||||
private HttpSession httpSession;
|
||||
private Node remote = null;
|
||||
// private HttpSession httpSession = null;
|
||||
private ChannelContext channelContext;
|
||||
|
||||
private HttpConfig httpConfig;
|
||||
@ -119,11 +116,11 @@ public class HttpRequest extends HttpPacket {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
public Cookie getCookie(String cooiename) {
|
||||
public Cookie getCookie(String cooieName) {
|
||||
if (cookieMap == null) {
|
||||
return null;
|
||||
}
|
||||
return cookieMap.get(cooiename);
|
||||
return cookieMap.get(cooieName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,34 +130,6 @@ public class HttpRequest extends HttpPacket {
|
||||
return cookieMap;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return the bodyBytes
|
||||
// */
|
||||
// public byte[] getBodyBytes() {
|
||||
// return bodyBytes;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param bodyBytes the bodyBytes to set
|
||||
// */
|
||||
// public void setBodyBytes(byte[] bodyBytes) {
|
||||
// this.bodyBytes = bodyBytes;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @return the userAgent
|
||||
// */
|
||||
// public UserAgent getUserAgent() {
|
||||
// return userAgent;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param userAgent the userAgent to set
|
||||
// */
|
||||
// public void setUserAgent(UserAgent userAgent) {
|
||||
// this.userAgent = userAgent;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return the cookies
|
||||
*/
|
||||
@ -250,13 +219,13 @@ public class HttpRequest extends HttpPacket {
|
||||
}
|
||||
|
||||
public void parseCookie() {
|
||||
String cookieline = headers.get(HttpConst.RequestHeaderKey.Cookie);
|
||||
if (StringUtils.isNotBlank(cookieline)) {
|
||||
String cookieLine = headers.get(HttpConst.RequestHeaderKey.Cookie);
|
||||
if (StringUtils.isNotBlank(cookieLine)) {
|
||||
cookies = new ArrayList<>();
|
||||
cookieMap = new HashMap<>();
|
||||
Map<String, String> _cookiemap = Cookie.getEqualMap(cookieline);
|
||||
Map<String, String> _cookieMap = Cookie.getEqualMap(cookieLine);
|
||||
List<Map<String, String>> cookieListMap = new ArrayList<>();
|
||||
for (Entry<String, String> cookieMapEntry : _cookiemap.entrySet()) {
|
||||
for (Entry<String, String> cookieMapEntry : _cookieMap.entrySet()) {
|
||||
HashMap<String, String> cookieOneMap = new HashMap<>();
|
||||
cookieOneMap.put(cookieMapEntry.getKey(), cookieMapEntry.getValue());
|
||||
cookieListMap.add(cookieOneMap);
|
||||
@ -264,15 +233,11 @@ 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.error("{}, 收到cookie:{}", channelContext, cookie.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBody(byte[] body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bodyFormat the bodyFormat to set
|
||||
*/
|
||||
@ -333,12 +298,6 @@ public class HttpRequest extends HttpPacket {
|
||||
if (headers != null) {
|
||||
parseCookie();
|
||||
}
|
||||
|
||||
// String Sec_WebSocket_Key = headers.get(HttpConst.RequestHeaderKey.Sec_WebSocket_Key);
|
||||
// if (StringUtils.isNoneBlank(Sec_WebSocket_Key)) {
|
||||
// ImSessionContext httpSession = channelContext.getAttribute();
|
||||
// httpSession.setWebsocket(true);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -387,18 +346,4 @@ public class HttpRequest extends HttpPacket {
|
||||
this.requestLine = requestLine;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return the httpSession
|
||||
// */
|
||||
// public HttpSession getHttpSession() {
|
||||
// return httpSession;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param httpSession the httpSession to set
|
||||
// */
|
||||
// public void setHttpSession(HttpSession httpSession) {
|
||||
// this.httpSession = httpSession;
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
*/
|
||||
public class HttpRequestDecoder {
|
||||
public static enum Step {
|
||||
firstline, header, body
|
||||
firstLine, header, body
|
||||
}
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(HttpRequestDecoder.class);
|
||||
@ -38,13 +38,13 @@ public class HttpRequestDecoder {
|
||||
/**
|
||||
* 头部,每行最大的字节数
|
||||
*/
|
||||
public static final int MAX_LENGTH_OF_HEADERLINE = 2048;
|
||||
public static final int MAX_LENGTH_OF_HEADER_LINE = 2048;
|
||||
|
||||
public static HttpRequest decode(ByteBuffer buffer, ChannelContext channelContext,boolean isBody) throws AioDecodeException {
|
||||
int initPosition = buffer.position();
|
||||
int readableLength = buffer.limit() - initPosition;
|
||||
// int count = 0;
|
||||
Step step = Step.firstline;
|
||||
Step step = Step.firstLine;
|
||||
// StringBuilder currLine = new StringBuilder();
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
int contentLength = 0;
|
||||
@ -55,7 +55,7 @@ public class HttpRequestDecoder {
|
||||
while (buffer.hasRemaining()) {
|
||||
String line;
|
||||
try {
|
||||
line = ByteBufferUtils.readLine(buffer, null, MAX_LENGTH_OF_HEADERLINE);
|
||||
line = ByteBufferUtils.readLine(buffer, null, MAX_LENGTH_OF_HEADER_LINE);
|
||||
} catch (LengthOverflowException e) {
|
||||
throw new AioDecodeException(e);
|
||||
}
|
||||
@ -70,7 +70,8 @@ public class HttpRequestDecoder {
|
||||
}
|
||||
|
||||
headerSb.append(line).append("\r\n");
|
||||
if ("".equals(line) && isBody) {//头部解析完成了
|
||||
//头部解析完成了
|
||||
if ("".equals(line) && isBody) {
|
||||
String contentLengthStr = headers.get(HttpConst.RequestHeaderKey.Content_Length);
|
||||
if (StringUtils.isBlank(contentLengthStr)) {
|
||||
contentLength = 0;
|
||||
@ -78,9 +79,9 @@ public class HttpRequestDecoder {
|
||||
contentLength = Integer.parseInt(contentLengthStr);
|
||||
}
|
||||
|
||||
// int readableLength = buffer.limit() - buffer.position();
|
||||
int headerLength = (buffer.position() - initPosition);
|
||||
int allNeedLength = headerLength + contentLength; //这个packet所需要的字节长度(含头部和体部)
|
||||
//这个packet所需要的字节长度(含头部和体部)
|
||||
int allNeedLength = headerLength + contentLength;
|
||||
if (readableLength >= allNeedLength) {
|
||||
step = Step.body;
|
||||
break;
|
||||
@ -89,12 +90,14 @@ public class HttpRequestDecoder {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (step == Step.firstline) {
|
||||
if (step == Step.firstLine) {
|
||||
firstLine = parseRequestLine(line, channelContext);
|
||||
step = Step.header;
|
||||
} else if (step == Step.header) {
|
||||
if("".equals(line) && !isBody)//不解析包体的话,结束(换句话说就是只解析请求行与请求头)
|
||||
//不解析包体的话,结束(换句话说就是只解析请求行与请求头)
|
||||
if("".equals(line) && !isBody) {
|
||||
break;
|
||||
}
|
||||
KeyValue keyValue = parseHeaderLine(line);
|
||||
headers.put(keyValue.getKey(), keyValue.getValue());
|
||||
}
|
||||
@ -121,9 +124,7 @@ public class HttpRequestDecoder {
|
||||
parseQueryString(httpRequest, firstLine, channelContext);
|
||||
|
||||
if (contentLength == 0) {
|
||||
// if (StringUtils.isNotBlank(firstLine.getQuery())) {
|
||||
// decodeParams(httpRequest.getParams(), firstLine.getQuery(), httpRequest.getCharset(), channelContext);
|
||||
// }
|
||||
|
||||
} else {
|
||||
bodyBytes = new byte[contentLength];
|
||||
buffer.get(bodyBytes);
|
||||
@ -131,26 +132,6 @@ public class HttpRequestDecoder {
|
||||
//解析消息体
|
||||
parseBody(httpRequest, firstLine, bodyBytes, channelContext);
|
||||
}
|
||||
|
||||
//解析User_Agent(浏览器操作系统等信息)
|
||||
// String User_Agent = headers.get(HttpConst.RequestHeaderKey.User_Agent);
|
||||
// if (StringUtils.isNotBlank(User_Agent)) {
|
||||
// // long start = System.currentTimeMillis();
|
||||
// UserAgentAnalyzer userAgentAnalyzer = UserAgentAnalyzerFactory.getUserAgentAnalyzer();
|
||||
// UserAgent userAgent = userAgentAnalyzer.parse(User_Agent);
|
||||
// httpRequest.setUserAgent(userAgent);
|
||||
// }
|
||||
|
||||
// StringBuilder logstr = new StringBuilder();
|
||||
// logstr.append("\r\n------------------ websocket header start ------------------------\r\n");
|
||||
// logstr.append(firstLine.getInitStr()).append("\r\n");
|
||||
// Set<Entry<String, String>> entrySet = headers.entrySet();
|
||||
// for (Entry<String, String> entry : entrySet) {
|
||||
// logstr.append(StringUtils.leftPad(entry.getKey(), 30)).append(" : ").append(entry.getValue()).append("\r\n");
|
||||
// }
|
||||
// logstr.append("------------------ websocket header start ------------------------\r\n");
|
||||
// log.error(logstr.toString());
|
||||
|
||||
return httpRequest;
|
||||
|
||||
}
|
||||
@ -159,24 +140,17 @@ public class HttpRequestDecoder {
|
||||
if (StrUtil.isBlank(paramsStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// // 去掉Path部分
|
||||
// int pathEndPos = paramsStr.indexOf('?');
|
||||
// if (pathEndPos > 0) {
|
||||
// paramsStr = StrUtil.subSuf(paramsStr, pathEndPos + 1);
|
||||
// }
|
||||
// Map<String, Object[]> ret = new HashMap<>();
|
||||
String[] keyvalues = StringUtils.split(paramsStr, "&");
|
||||
for (String keyvalue : keyvalues) {
|
||||
String[] keyvalueArr = StringUtils.split(keyvalue, "=");
|
||||
if (keyvalueArr.length != 2) {
|
||||
String[] keyValues = StringUtils.split(paramsStr, "&");
|
||||
for (String keyValue : keyValues) {
|
||||
String[] keyValueArr = StringUtils.split(keyValue, "=");
|
||||
if (keyValueArr.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = keyvalueArr[0];
|
||||
String key = keyValueArr[0];
|
||||
String value = null;
|
||||
try {
|
||||
value = URLDecoder.decode(keyvalueArr[1], charset);
|
||||
value = URLDecoder.decode(keyValueArr[1], charset);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error(channelContext.toString(), e);
|
||||
}
|
||||
@ -195,17 +169,6 @@ public class HttpRequestDecoder {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*
|
||||
* @author WChao
|
||||
* 2017年2月22日 下午4:06:42
|
||||
*
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析消息体
|
||||
* @param httpRequest
|
||||
@ -237,9 +200,9 @@ public class HttpRequestDecoder {
|
||||
}
|
||||
|
||||
//【multipart/form-data; boundary=----WebKitFormBoundaryuwYcfA2AIgxqIxA0】
|
||||
String initboundary = HttpParseUtils.getPerprotyEqualValue(httpRequest.getHeaders(), HttpConst.RequestHeaderKey.Content_Type, "boundary");
|
||||
log.debug("{}, initboundary:{}", channelContext, initboundary);
|
||||
HttpMultiBodyDecoder.decode(httpRequest, firstLine, bodyBytes, initboundary, channelContext);
|
||||
String initBoundary = HttpParseUtils.getPerprotyEqualValue(httpRequest.getHeaders(), HttpConst.RequestHeaderKey.Content_Type, "boundary");
|
||||
log.debug("{}, initBoundary:{}", channelContext, initBoundary);
|
||||
HttpMultiBodyDecoder.decode(httpRequest, firstLine, bodyBytes, initBoundary, channelContext);
|
||||
} else {
|
||||
String bodyString = null;
|
||||
if (bodyBytes != null && bodyBytes.length > 0) {
|
||||
@ -260,26 +223,6 @@ public class HttpRequestDecoder {
|
||||
}
|
||||
}
|
||||
|
||||
// private static void parseText(HttpRequestPacket httpRequest, RequestLine firstLine, byte[] bodyBytes, String bodyString) {
|
||||
// String paramStr = "";
|
||||
// if (StringUtils.isNotBlank(firstLine.getQueryStr())) {
|
||||
// paramStr += firstLine.getQueryStr();
|
||||
// }
|
||||
// if (bodyString != null) {
|
||||
// if (paramStr != null) {
|
||||
// paramStr += "&";
|
||||
// }
|
||||
// paramStr += bodyString;
|
||||
// }
|
||||
//
|
||||
// if (paramStr != null) {
|
||||
// Map<String, List<String>> params = HttpUtil.decodeParams(paramStr, httpRequest.getCharset());
|
||||
// httpRequest.setParams(params);
|
||||
// log.error("paramStr:{}", paramStr);
|
||||
// log.error("param:{}", Json.toJson(params));
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Content-Type : application/x-www-form-urlencoded; charset=UTF-8
|
||||
* Content-Type : application/x-www-form-urlencoded; charset=UTF-8
|
||||
@ -311,10 +254,8 @@ public class HttpRequestDecoder {
|
||||
* 解析请求头的每一行
|
||||
* @param line
|
||||
* @return
|
||||
*
|
||||
* @author WChao
|
||||
* 2017年2月23日 下午1:37:58
|
||||
*
|
||||
*/
|
||||
public static KeyValue parseHeaderLine(String line) {
|
||||
KeyValue keyValue = new KeyValue();
|
||||
@ -349,15 +290,17 @@ public class HttpRequestDecoder {
|
||||
String _method = StringUtils.upperCase(line.substring(0, index1));
|
||||
Method method = Method.from(_method);
|
||||
int index2 = line.indexOf(' ', index1 + 1);
|
||||
String pathAndQuerystr = line.substring(index1 + 1, index2); // "/user/get?name=999"
|
||||
String path = null; //"/user/get"
|
||||
// "/user/get?name=999"
|
||||
String pathAndQueryStr = line.substring(index1 + 1, index2);
|
||||
//"/user/get"
|
||||
String path = null;
|
||||
String queryStr = null;
|
||||
int indexOfQuestionmark = pathAndQuerystr.indexOf("?");
|
||||
if (indexOfQuestionmark != -1) {
|
||||
queryStr = StringUtils.substring(pathAndQuerystr, indexOfQuestionmark + 1);
|
||||
path = StringUtils.substring(pathAndQuerystr, 0, indexOfQuestionmark);
|
||||
int indexOfQuestionMark = pathAndQueryStr.indexOf("?");
|
||||
if (indexOfQuestionMark != -1) {
|
||||
queryStr = StringUtils.substring(pathAndQueryStr, indexOfQuestionMark + 1);
|
||||
path = StringUtils.substring(pathAndQueryStr, 0, indexOfQuestionMark);
|
||||
} else {
|
||||
path = pathAndQuerystr;
|
||||
path = pathAndQueryStr;
|
||||
queryStr = "";
|
||||
}
|
||||
|
||||
@ -370,7 +313,7 @@ public class HttpRequestDecoder {
|
||||
requestLine.setMethod(method);
|
||||
requestLine.setPath(path);
|
||||
requestLine.setInitPath(path);
|
||||
requestLine.setPathAndQuery(pathAndQuerystr);
|
||||
requestLine.setPathAndQuery(pathAndQueryStr);
|
||||
requestLine.setQuery(queryStr);
|
||||
requestLine.setVersion(version);
|
||||
requestLine.setProtocol(protocol);
|
||||
@ -389,17 +332,6 @@ public class HttpRequestDecoder {
|
||||
* @author WChao
|
||||
*/
|
||||
private static void parseUrlencoded(HttpRequest httpRequest, RequestLine firstLine, byte[] bodyBytes, String bodyString, ChannelContext channelContext) {
|
||||
// String paramStr = "";
|
||||
// if (StringUtils.isNotBlank(firstLine.getQuery())) {
|
||||
// paramStr += firstLine.getQuery();
|
||||
// }
|
||||
// if (bodyString != null) {
|
||||
// if (paramStr != null) {
|
||||
// paramStr += "&";
|
||||
// }
|
||||
// paramStr += bodyString;
|
||||
// }
|
||||
|
||||
if (StringUtils.isNotBlank(bodyString)) {
|
||||
decodeParams(httpRequest.getParams(), bodyString, httpRequest.getCharset(), channelContext);
|
||||
}
|
||||
@ -419,7 +351,6 @@ public class HttpRequestDecoder {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author WChao
|
||||
* 2017年2月22日 下午4:06:42
|
||||
|
@ -125,6 +125,7 @@ public class HttpResponse extends HttpPacket {
|
||||
/**
|
||||
* @return the status
|
||||
*/
|
||||
@Override
|
||||
public HttpResponseStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import org.tio.core.GroupContext;
|
||||
*/
|
||||
public class HttpResponseEncoder {
|
||||
public static enum Step {
|
||||
firstline, header, body
|
||||
firstLine, header, body
|
||||
}
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(HttpResponseEncoder.class);
|
||||
|
@ -54,10 +54,6 @@ public class HttpSession extends ImSessionContext implements java.io.Serializabl
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
@ -84,8 +80,4 @@ public class HttpSession extends ImSessionContext implements java.io.Serializabl
|
||||
public void setData(Map<String, Serializable> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
@ -9,25 +9,35 @@ import org.tio.core.ChannelContext;
|
||||
|
||||
/**
|
||||
* @author WChao
|
||||
*
|
||||
* @date 2018-09-05 23:52:00
|
||||
*/
|
||||
public abstract class AbProtocol implements IProtocol {
|
||||
//协议包转化器;
|
||||
private IConvertProtocolPacket convertor;
|
||||
/**
|
||||
* 协议包转化器;
|
||||
*/
|
||||
private IConvertProtocolPacket converter;
|
||||
|
||||
public AbProtocol(){
|
||||
this.convertor = convertor();
|
||||
this.converter = converter();
|
||||
}
|
||||
public abstract boolean isProtoc(ByteBuffer buffer,ChannelContext channelContext) throws Throwable;
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 根据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 isProtoc(copyByteBuffer, channelContext);
|
||||
return isProtocolByBuffer(copyByteBuffer, channelContext);
|
||||
}
|
||||
public IConvertProtocolPacket getConvertor() {
|
||||
return convertor;
|
||||
public IConvertProtocolPacket getConverter() {
|
||||
return converter;
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,24 @@ import org.tio.core.ChannelContext;
|
||||
*
|
||||
*/
|
||||
public interface IProtocol {
|
||||
public abstract String name();
|
||||
public abstract boolean isProtocol(ByteBuffer byteBuffer,ChannelContext channelContext)throws Throwable;
|
||||
public abstract boolean isProtocol(ImPacket imPacket,ChannelContext channelContext)throws Throwable;
|
||||
public abstract IConvertProtocolPacket convertor();
|
||||
/**
|
||||
* 协议名称
|
||||
* @return 如:http、ws、tcp等
|
||||
*/
|
||||
public String name();
|
||||
|
||||
/**
|
||||
* 判断是否属于指定协议
|
||||
* @param imPacket
|
||||
* @param channelContext
|
||||
* @return
|
||||
* @throws Throwable
|
||||
*/
|
||||
public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext)throws Throwable;
|
||||
|
||||
/**
|
||||
* 获取该协议包转化器
|
||||
* @return
|
||||
*/
|
||||
public IConvertProtocolPacket converter();
|
||||
}
|
||||
|
@ -26,14 +26,16 @@ public class TcpProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtoc(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
|
||||
if(imSessionContext != null && imSessionContext instanceof TcpSessionContext)
|
||||
if(imSessionContext != null && imSessionContext instanceof TcpSessionContext) {
|
||||
return true;
|
||||
}
|
||||
if(buffer != null){
|
||||
//获取第一个字节协议版本号;
|
||||
byte version = buffer.get();
|
||||
if(version == Protocol.VERSION){//TCP协议;
|
||||
//TCP协议;
|
||||
if(version == Protocol.VERSION){
|
||||
channelContext.setAttribute(new TcpSessionContext());
|
||||
ImUtils.setClient(channelContext);
|
||||
return true;
|
||||
@ -43,14 +45,15 @@ public class TcpProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IConvertProtocolPacket convertor() {
|
||||
public IConvertProtocolPacket converter() {
|
||||
return new TcpConvertPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
|
||||
if(imPacket == null)
|
||||
if(imPacket == null) {
|
||||
return false;
|
||||
}
|
||||
if(imPacket instanceof TcpPacket){
|
||||
Object sessionContext = channelContext.getAttribute();
|
||||
if(sessionContext == null){
|
||||
|
@ -16,15 +16,17 @@ import org.jim.common.packets.Command;
|
||||
/**
|
||||
* 版本: [1.0]
|
||||
* 功能说明:
|
||||
* 作者: WChao 创建时间: 2017年8月21日 下午3:08:04
|
||||
* @author : WChao 创建时间: 2017年8月21日 下午3:08:04
|
||||
*/
|
||||
public class TcpServerDecoder {
|
||||
|
||||
private static Logger logger = Logger.getLogger(TcpServerDecoder.class);
|
||||
|
||||
public static TcpPacket decode(ByteBuffer buffer, ChannelContext channelContext) throws AioDecodeException{
|
||||
if(!isHeaderLength(buffer))//校验协议头
|
||||
//校验协议头
|
||||
if(!isHeaderLength(buffer)) {
|
||||
return null;
|
||||
}
|
||||
//获取第一个字节协议版本号;
|
||||
byte version = buffer.get();
|
||||
if(version != Protocol.VERSION){
|
||||
@ -33,7 +35,8 @@ public class TcpServerDecoder {
|
||||
//标志位
|
||||
byte maskByte = buffer.get();
|
||||
Integer synSeq = 0;
|
||||
if(ImPacket.decodeHasSynSeq(maskByte)){//同步发送;
|
||||
//同步发送;
|
||||
if(ImPacket.decodeHasSynSeq(maskByte)){
|
||||
synSeq = buffer.getInt();
|
||||
}
|
||||
//cmd命令码
|
||||
@ -49,7 +52,8 @@ public class TcpServerDecoder {
|
||||
}
|
||||
int readableLength = buffer.limit() - buffer.position();
|
||||
int validateBodyLen = readableLength - bodyLen;
|
||||
if (validateBodyLen < 0) // 不够消息体长度(剩下的buffe组不了消息体)
|
||||
// 不够消息体长度(剩下的buffer组不了消息体)
|
||||
if (validateBodyLen < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -60,11 +64,12 @@ public class TcpServerDecoder {
|
||||
logger.error(e.toString());
|
||||
}
|
||||
logger.info("TCP解码成功...");
|
||||
//bytebuffer的总长度是 = 1byte协议版本号+1byte消息标志位+4byte同步序列号(如果是同步发送则多4byte同步序列号,否则无4byte序列号)+1byte命令码+4byte消息的长度+消息体的长度
|
||||
//byteBuffer的总长度是 = 1byte协议版本号+1byte消息标志位+4byte同步序列号(如果是同步发送则多4byte同步序列号,否则无4byte序列号)+1byte命令码+4byte消息的长度+消息体的长度
|
||||
TcpPacket tcpPacket = new TcpPacket(Command.forNumber(cmdByte), body);
|
||||
tcpPacket.setVersion(version);
|
||||
tcpPacket.setMask(maskByte);
|
||||
if(synSeq > 0){//同步发送设置同步序列号
|
||||
//同步发送设置同步序列号
|
||||
if(synSeq > 0){
|
||||
tcpPacket.setSynSeq(synSeq);
|
||||
try {
|
||||
channelContext.getGroupContext().getAioHandler().handler(tcpPacket, channelContext);
|
||||
@ -82,8 +87,9 @@ public class TcpServerDecoder {
|
||||
*/
|
||||
private static boolean isHeaderLength(ByteBuffer buffer) throws AioDecodeException{
|
||||
int readableLength = buffer.limit() - buffer.position();
|
||||
if(readableLength == 0)
|
||||
if(readableLength == 0) {
|
||||
return false;
|
||||
}
|
||||
//协议头索引;
|
||||
int index = buffer.position();
|
||||
try{
|
||||
@ -92,7 +98,8 @@ public class TcpServerDecoder {
|
||||
index++;
|
||||
//标志位
|
||||
byte maskByte = buffer.get(index);
|
||||
if(ImPacket.decodeHasSynSeq(maskByte)){//同步发送;
|
||||
//同步发送;
|
||||
if(ImPacket.decodeHasSynSeq(maskByte)){
|
||||
index += 4;
|
||||
}
|
||||
index++;
|
||||
|
@ -13,7 +13,7 @@ import org.tio.core.GroupContext;
|
||||
/**
|
||||
* 版本: [1.0]
|
||||
* 功能说明:
|
||||
* 作者: WChao 创建时间: 2017年8月21日 下午4:00:31
|
||||
* @author : WChao 创建时间: 2017年8月21日 下午4:00:31
|
||||
*/
|
||||
public class TcpServerEncoder {
|
||||
|
||||
@ -37,13 +37,15 @@ public class TcpServerEncoder {
|
||||
maskByte = ImPacket.encodeHasSynSeq(maskByte, isHasSynSeq);
|
||||
maskByte = ImPacket.encode4ByteLength(maskByte, is4ByteLength);
|
||||
byte cmdByte = 0x00;
|
||||
if(tcpPacket.getCommand() != null)
|
||||
cmdByte = (byte) (cmdByte|tcpPacket.getCommand().getNumber());//消息类型;
|
||||
//消息类型;
|
||||
if(tcpPacket.getCommand() != null) {
|
||||
cmdByte = (byte) (cmdByte | tcpPacket.getCommand().getNumber());
|
||||
}
|
||||
|
||||
tcpPacket.setVersion(version);
|
||||
tcpPacket.setMask(maskByte);
|
||||
|
||||
//bytebuffer的总长度是 = 1byte协议版本号+1byte消息标志位+4byte同步序列号(如果是同步发送则都4byte同步序列号,否则无4byte序列号)+1byte命令码+4byte消息的长度+消息体
|
||||
//byteBuffer的总长度是 = 1byte协议版本号+1byte消息标志位+4byte同步序列号(如果是同步发送则都4byte同步序列号,否则无4byte序列号)+1byte命令码+4byte消息的长度+消息体
|
||||
int allLen = 1+1;
|
||||
if(isHasSynSeq){
|
||||
allLen += 4;
|
||||
@ -55,7 +57,8 @@ public class TcpServerEncoder {
|
||||
buffer.order(byteOrder);
|
||||
buffer.put(tcpPacket.getVersion());
|
||||
buffer.put(tcpPacket.getMask());
|
||||
if(isHasSynSeq){//同步发送设置4byte,同步序列号;
|
||||
//同步发送设置4byte,同步序列号;
|
||||
if(isHasSynSeq){
|
||||
buffer.putInt(tcpPacket.getSynSeq());
|
||||
}
|
||||
buffer.put(cmdByte);
|
||||
|
@ -19,12 +19,15 @@ 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
|
||||
* @author WChao
|
||||
*
|
||||
*/
|
||||
public class ChatKit {
|
||||
|
||||
private static Logger log = Logger.getLogger(ChatKit.class);
|
||||
|
||||
/**
|
||||
* 转换为聊天消息结构;
|
||||
* @param body
|
||||
@ -46,14 +49,16 @@ public class ChatKit {
|
||||
}
|
||||
return chatReqBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否属于指定格式聊天消息;
|
||||
* @param packet
|
||||
* @param body
|
||||
* @return
|
||||
*/
|
||||
private static ChatBody parseChatBody(byte[] body){
|
||||
if(body == null)
|
||||
if(body == null) {
|
||||
return null;
|
||||
}
|
||||
ChatBody chatReqBody = null;
|
||||
try{
|
||||
String text = new String(body,HttpConst.CHARSET_NAME);
|
||||
@ -66,18 +71,20 @@ public class ChatKit {
|
||||
return chatReqBody;
|
||||
}
|
||||
}catch(Exception e){
|
||||
|
||||
log.error(e.toString());
|
||||
}
|
||||
return chatReqBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否属于指定格式聊天消息;
|
||||
* @param packet
|
||||
* @param bodyStr
|
||||
* @return
|
||||
*/
|
||||
public static ChatBody parseChatBody(String bodyStr){
|
||||
if(bodyStr == null)
|
||||
if(bodyStr == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return parseChatBody(bodyStr.getBytes(HttpConst.CHARSET_NAME));
|
||||
} catch (Exception e) {
|
||||
@ -85,24 +92,24 @@ public class ChatKit {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 聊天数据格式不正确响应包
|
||||
* @param chatBody
|
||||
* @param channelContext
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
/**
|
||||
* 聊天数据格式不正确响应包
|
||||
* @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 chatBody
|
||||
* @param channelContext
|
||||
* @return
|
||||
* @return imPacket
|
||||
* @throws Exception
|
||||
*/
|
||||
public static ImPacket sendSuccessRespPacket(ChannelContext channelContext) throws Exception{
|
||||
@ -111,9 +118,9 @@ public class ChatKit {
|
||||
respPacket.setStatus(ImStatus.C10000);
|
||||
return respPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 聊天用户不在线响应包
|
||||
* @param chatBody
|
||||
* @param channelContext
|
||||
* @return
|
||||
* @throws Exception
|
||||
@ -124,24 +131,27 @@ public class ChatKit {
|
||||
respPacket.setStatus(ImStatus.C10001);
|
||||
return respPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断用户是否在线;
|
||||
* @param userid
|
||||
* 判断用户是否在线
|
||||
* @param userId
|
||||
* @param imConfig
|
||||
* @return
|
||||
*/
|
||||
public static boolean isOnline(String userid ,Config imConfig){
|
||||
public static boolean isOnline(String userId ,Config imConfig){
|
||||
boolean isStore = Const.ON.equals(imConfig.getIsStore());
|
||||
if(isStore){
|
||||
return imConfig.getMessageHelper().isOnline(userid);
|
||||
return imConfig.getMessageHelper().isOnline(userId);
|
||||
}
|
||||
SetWithLock<ChannelContext> toChannleContexts = ImAio.getChannelContextsByUserid(userid);
|
||||
if(toChannleContexts != null && toChannleContexts.size() > 0){
|
||||
SetWithLock<ChannelContext> toChannelContexts = ImAio.getChannelContextsByUserId(userId);
|
||||
if(toChannelContexts != null && toChannelContexts.size() > 0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取双方会话ID(算法,from与to相与的值通过MD5加密得出)
|
||||
* 获取双方会话ID(算法,from与to相与的值通过MD5加密得出)
|
||||
* @param from
|
||||
* @param to
|
||||
* @return
|
||||
@ -149,29 +159,29 @@ public class ChatKit {
|
||||
public static String sessionId(String from , String to){
|
||||
String sessionId = "";
|
||||
try{
|
||||
byte[] fbytes = from.getBytes(Const.CHARSET);
|
||||
byte[] tbytes = to.getBytes(Const.CHARSET);
|
||||
boolean isfmax = fbytes.length > tbytes.length;
|
||||
boolean isequal = fbytes.length == tbytes.length;
|
||||
if(isfmax){
|
||||
for(int i = 0 ; i < fbytes.length ; i++){
|
||||
for(int j = 0 ; j < tbytes.length ; j++){
|
||||
fbytes[i] = (byte) (fbytes[i]^tbytes[j]);
|
||||
byte[] fBytes = from.getBytes(Const.CHARSET);
|
||||
byte[] tBytes = to.getBytes(Const.CHARSET);
|
||||
boolean isFromMax = fBytes.length > tBytes.length;
|
||||
boolean isEqual = fBytes.length == tBytes.length;
|
||||
if(isFromMax){
|
||||
for(int i = 0 ; i < fBytes.length ; i++){
|
||||
for(int j = 0 ; j < tBytes.length ; j++){
|
||||
fBytes[i] = (byte) (fBytes[i]^tBytes[j]);
|
||||
}
|
||||
}
|
||||
sessionId = new String(fbytes);
|
||||
}else if(isequal){
|
||||
for(int i = 0 ; i < fbytes.length ; i++){
|
||||
fbytes[i] = (byte) (fbytes[i]^tbytes[i]);
|
||||
sessionId = new String(fBytes);
|
||||
}else if(isEqual){
|
||||
for(int i = 0 ; i < fBytes.length ; i++){
|
||||
fBytes[i] = (byte) (fBytes[i]^tBytes[i]);
|
||||
}
|
||||
sessionId = new String(fbytes);
|
||||
sessionId = new String(fBytes);
|
||||
}else{
|
||||
for(int i = 0 ; i < tbytes.length ; i++){
|
||||
for(int j = 0 ; j < fbytes.length ; j++){
|
||||
tbytes[i] = (byte) (tbytes[i]^fbytes[j]);
|
||||
for(int i = 0 ; i < tBytes.length ; i++){
|
||||
for(int j = 0 ; j < fBytes.length ; j++){
|
||||
tBytes[i] = (byte) (tBytes[i]^fBytes[j]);
|
||||
}
|
||||
}
|
||||
sessionId = new String(tbytes);
|
||||
sessionId = new String(tBytes);
|
||||
}
|
||||
}catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
|
@ -47,19 +47,20 @@ public class ImKit {
|
||||
protocols.put(tcpProtocol.name(),tcpProtocol);
|
||||
protocols.put(httpProtocol.name(),httpProtocol);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 功能描述:[转换不同协议响应包]
|
||||
* 创建者:WChao 创建时间: 2017年9月21日 下午3:21:54
|
||||
* @param body
|
||||
* @param channelContext
|
||||
* @return
|
||||
*
|
||||
* 功能描述:[转换不同协议响应包]
|
||||
* @author:WChao 创建时间: 2017年9月21日 下午3:21:54
|
||||
* @param body
|
||||
* @param channelContext
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static ImPacket ConvertRespPacket(RespBody respBody, ChannelContext channelContext){
|
||||
ImPacket respPacket = null;
|
||||
if(respBody == null)
|
||||
if(respBody == null) {
|
||||
return respPacket;
|
||||
}
|
||||
byte[] body;
|
||||
try {
|
||||
body = respBody.toString().getBytes(HttpConst.CHARSET_NAME);
|
||||
@ -69,27 +70,27 @@ public class ImKit {
|
||||
}
|
||||
return respPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 功能描述:[转换不同协议响应包]
|
||||
* 创建者:WChao 创建时间: 2017年9月21日 下午3:21:54
|
||||
* @param body
|
||||
* @param channelContext
|
||||
* @return
|
||||
*
|
||||
* 功能描述:[转换不同协议响应包]
|
||||
* @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 convertor = (IConvertProtocolPacket)channelContext.getAttribute(Const.CONVERTOR);
|
||||
if(convertor != null){
|
||||
return convertor.RespPacket(body, command, channelContext);
|
||||
IConvertProtocolPacket converter = (IConvertProtocolPacket)channelContext.getAttribute(Const.CONVERTOR);
|
||||
if(converter != null){
|
||||
return converter.RespPacket(body, command, channelContext);
|
||||
}
|
||||
for(Entry<String,AbProtocol> entry : protocols.entrySet()){
|
||||
AbProtocol protocol = entry.getValue();
|
||||
IConvertProtocolPacket convertorObj = protocol.getConvertor();
|
||||
respPacket = convertorObj.RespPacket(body, command, channelContext);
|
||||
IConvertProtocolPacket converterObj = protocol.getConverter();
|
||||
respPacket = converterObj.RespPacket(body, command, channelContext);
|
||||
if(respPacket != null){
|
||||
channelContext.setAttribute(Const.CONVERTOR, convertorObj);
|
||||
channelContext.setAttribute(Const.CONVERTOR, converterObj);
|
||||
return respPacket;
|
||||
}
|
||||
}
|
||||
@ -104,10 +105,10 @@ public class ImKit {
|
||||
try{
|
||||
boolean isProtocol = protocol.isProtocol(imPacket,channelContext);
|
||||
if(isProtocol){
|
||||
IConvertProtocolPacket convertorObj = protocol.getConvertor();
|
||||
respPacket = convertorObj.RespPacket(imPacket.getBody(), command, channelContext);
|
||||
IConvertProtocolPacket converterObj = protocol.getConverter();
|
||||
respPacket = converterObj.RespPacket(imPacket.getBody(), command, channelContext);
|
||||
if(respPacket != null){
|
||||
channelContext.setAttribute(Const.CONVERTOR, convertorObj);
|
||||
channelContext.setAttribute(Const.CONVERTOR, converterObj);
|
||||
return respPacket;
|
||||
}
|
||||
}
|
||||
@ -118,6 +119,7 @@ public class ImKit {
|
||||
}
|
||||
return respPacket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所属终端协议;
|
||||
* @param byteBuffer
|
||||
@ -127,8 +129,8 @@ public class ImKit {
|
||||
for(Entry<String,AbProtocol> entry : protocols.entrySet()){
|
||||
AbProtocol protocol = entry.getValue();
|
||||
try {
|
||||
boolean isPrototol = protocol.isProtocol(byteBuffer, channelContext);
|
||||
if(isPrototol){
|
||||
boolean isProtocol = protocol.isProtocol(byteBuffer, channelContext);
|
||||
if(isProtocol){
|
||||
return protocol;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
@ -137,6 +139,7 @@ public class ImKit {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化状态码消息响应体;
|
||||
* @param status
|
||||
@ -145,8 +148,9 @@ public class ImKit {
|
||||
public static byte[] toImStatusBody(ImStatus status){
|
||||
return JsonKit.toJsonBytes(new RespBody().setCode(status.getCode()).setMsg(status.getDescription()+" "+status.getText()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有协议判断器,目前内置(HttpProtocol、WebsocketProtocol、HttpProtocol)
|
||||
* 获取所有协议判断器,目前内置(HttpProtocol、WebSocketProtocol、HttpProtocol)
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, AbProtocol> getProtocols() {
|
||||
@ -154,63 +158,68 @@ public class ImKit {
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制用户信息不包括frieds、groups下的users信息;
|
||||
* 复制用户信息不包括friends、groups下的users信息;
|
||||
* @param source
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static User copyUserWithoutFriendsGroups(User source){
|
||||
if(source == null)
|
||||
return null;
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(source, user,"friends","groups");
|
||||
if(source == null) {
|
||||
return null;
|
||||
}
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(source, user,"friends","groups");
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制用户信息不包括frieds、groups下的users信息;
|
||||
* 复制用户信息不包括friends、groups下的users信息;
|
||||
* @param source
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static User copyUserWithoutUsers(User source){
|
||||
if(source == null)
|
||||
return null;
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(source, user,"friends","groups");
|
||||
List<Group> friends = source.getFriends();
|
||||
if(friends != null && !friends.isEmpty()){
|
||||
List<Group> newFriends = new ArrayList<Group>();
|
||||
for(Group friend : friends){
|
||||
Group newFriend = new Group();
|
||||
BeanUtil.copyProperties(friend, newFriend);
|
||||
newFriend.setUsers(null);
|
||||
newFriends.add(newFriend);
|
||||
}
|
||||
user.setFriends(newFriends);
|
||||
}
|
||||
List<Group> groups = source.getGroups();
|
||||
if(groups != null && !groups.isEmpty()){
|
||||
List<Group> newGroups = new ArrayList<Group>();
|
||||
for(Group group : newGroups){
|
||||
Group newGroup = new Group();
|
||||
BeanUtil.copyProperties(group, newGroup);
|
||||
newGroup.setUsers(null);
|
||||
newGroups.add(newGroup);
|
||||
}
|
||||
user.setGroups(newGroups);
|
||||
}
|
||||
if(source == null){
|
||||
return source;
|
||||
}
|
||||
User user = new User();
|
||||
BeanUtil.copyProperties(source, user,"friends","groups");
|
||||
List<Group> friends = source.getFriends();
|
||||
if(friends != null && !friends.isEmpty()){
|
||||
List<Group> newFriends = new ArrayList<Group>();
|
||||
for(Group friend : friends){
|
||||
Group newFriend = new Group();
|
||||
BeanUtil.copyProperties(friend, newFriend);
|
||||
newFriend.setUsers(null);
|
||||
newFriends.add(newFriend);
|
||||
}
|
||||
user.setFriends(newFriends);
|
||||
}
|
||||
List<Group> groups = source.getGroups();
|
||||
if(groups != null && !groups.isEmpty()){
|
||||
List<Group> newGroups = new ArrayList<Group>();
|
||||
for(Group group : groups){
|
||||
Group newGroup = new Group();
|
||||
BeanUtil.copyProperties(group, newGroup);
|
||||
newGroup.setUsers(null);
|
||||
newGroups.add(newGroup);
|
||||
}
|
||||
user.setGroups(newGroups);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制分组或者群组,不包括users;
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static Group copyGroupWithoutUsers(Group source){
|
||||
if(source == null)
|
||||
return null;
|
||||
Group group = new Group();
|
||||
BeanUtil.copyProperties(source, group,"users");
|
||||
return group;
|
||||
}
|
||||
if(source == null) {
|
||||
return null;
|
||||
}
|
||||
Group group = new Group();
|
||||
BeanUtil.copyProperties(source, group,"users");
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
@ -125,8 +125,9 @@ public class JsonKit {
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> toArray(List<String> datas, Class<T> clazz){
|
||||
if(datas == null)
|
||||
if(datas == null) {
|
||||
return null;
|
||||
}
|
||||
List<T> result = new ArrayList<T>();
|
||||
for(String obj : datas){
|
||||
result.add(toBean(obj, clazz));
|
||||
|
@ -17,7 +17,7 @@ import org.jim.common.utils.ImUtils;
|
||||
import org.tio.core.ChannelContext;
|
||||
|
||||
/**
|
||||
* Websocket协议
|
||||
* WebSocket协议判断器
|
||||
* @author WChao
|
||||
*
|
||||
*/
|
||||
@ -29,11 +29,13 @@ public class WsProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtoc(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
public boolean isProtocolByBuffer(ByteBuffer buffer,ChannelContext channelContext) throws Throwable {
|
||||
ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
|
||||
if(imSessionContext != null && imSessionContext instanceof WsSessionContext)
|
||||
if(imSessionContext != null && imSessionContext instanceof WsSessionContext) {
|
||||
return true;
|
||||
if(buffer != null){//第一次连接;
|
||||
}
|
||||
//第一次连接;
|
||||
if(buffer != null){
|
||||
HttpRequest request = HttpRequestDecoder.decode(buffer, channelContext,false);
|
||||
if(request.getHeaders().get(HttpConst.RequestHeaderKey.Sec_WebSocket_Key) != null)
|
||||
{
|
||||
@ -46,14 +48,15 @@ public class WsProtocol extends AbProtocol {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IConvertProtocolPacket convertor() {
|
||||
public IConvertProtocolPacket converter() {
|
||||
return new WsConvertPacket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext) throws Throwable {
|
||||
if(imPacket == null)
|
||||
if(imPacket == null) {
|
||||
return false;
|
||||
}
|
||||
if(imPacket instanceof WsPacket){
|
||||
Object sessionContext = channelContext.getAttribute();
|
||||
if(sessionContext == null){
|
||||
|
@ -7,7 +7,7 @@ import org.jim.common.http.HttpConst;
|
||||
*
|
||||
* 版本: [1.0]
|
||||
* 功能说明:
|
||||
* 作者: WChao 创建时间: 2017年9月6日 上午11:11:26
|
||||
* @author : WChao 创建时间: 2017年9月6日 上午11:11:26
|
||||
*/
|
||||
public class WsServerConfig extends Config{
|
||||
|
||||
@ -20,35 +20,10 @@ public class WsServerConfig extends Config{
|
||||
private IWsMsgHandler wsMsgHandler;
|
||||
|
||||
public WsServerConfig(){};
|
||||
/**
|
||||
*
|
||||
* @author: WChao
|
||||
*/
|
||||
|
||||
public WsServerConfig(Integer bindPort) {
|
||||
|
||||
this.bindPort = bindPort;
|
||||
}
|
||||
/**
|
||||
* @return the bindIp
|
||||
*/
|
||||
public String getBindIp() {
|
||||
return bindIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bindIp the bindIp to set
|
||||
*/
|
||||
public void setBindIp(String bindIp) {
|
||||
this.bindIp = bindIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the bindPort
|
||||
*/
|
||||
public Integer getBindPort() {
|
||||
return bindPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the charset
|
||||
*/
|
||||
@ -68,7 +43,4 @@ public class WsServerConfig extends Config{
|
||||
public void setWsMsgHandler(IWsMsgHandler wsMsgHandler) {
|
||||
this.wsMsgHandler = wsMsgHandler;
|
||||
}
|
||||
public void setBindPort(Integer bindPort) {
|
||||
this.bindPort = bindPort;
|
||||
}
|
||||
}
|
||||
|
@ -78,20 +78,6 @@ public class WsSessionContext extends ImSessionContext {
|
||||
return lastParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the requestRateLimiter
|
||||
*/
|
||||
public RateLimiterWrap getRequestRateLimiter() {
|
||||
return requestRateLimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the token
|
||||
*/
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the isHandshaked
|
||||
*/
|
||||
@ -127,20 +113,6 @@ public class WsSessionContext extends ImSessionContext {
|
||||
this.lastParts = lastParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param requestRateLimiter the requestRateLimiter to set
|
||||
*/
|
||||
public void setRequestRateLimiter(RateLimiterWrap requestRateLimiter) {
|
||||
this.requestRateLimiter = requestRateLimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token the token to set
|
||||
*/
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public WsRequestPacket getWsRequestPacket() {
|
||||
return wsRequestPacket;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import com.jfinal.kit.PropKit;
|
||||
*
|
||||
*/
|
||||
public class ImServerDemoStart {
|
||||
|
||||
|
||||
public static void main(String[] args)throws Exception{
|
||||
ImConfig imConfig = new PropertyImConfigBuilder("jim.properties").build();
|
||||
initSsl(imConfig);//初始化SSL;(开启SSL之前,你要保证你有SSL证书哦...)
|
||||
|
@ -13,6 +13,7 @@ import org.jim.common.packets.CloseReqBody;
|
||||
import org.jim.common.packets.Command;
|
||||
import org.jim.common.packets.RespBody;
|
||||
import org.jim.common.packets.User;
|
||||
import org.jim.server.command.CommandManager;
|
||||
import org.jim.server.command.handler.ChatReqHandler;
|
||||
import org.jim.server.command.handler.CloseReqHandler;
|
||||
import org.jim.server.http.annotation.RequestPath;
|
||||
@ -20,8 +21,8 @@ import org.jim.server.util.HttpResps;
|
||||
import org.tio.core.ChannelContext;
|
||||
/**
|
||||
* 版本: [1.0]
|
||||
* 功能说明:
|
||||
* 作者: WChao 创建时间: 2017年8月8日 上午9:08:48
|
||||
* 功能说明: Http协议消息发送控制器类
|
||||
* @author : WChao 创建时间: 2017年8月8日 上午9:08:48
|
||||
*/
|
||||
@RequestPath(value = "/api")
|
||||
public class HttpApiController {
|
||||
@ -29,7 +30,8 @@ public class HttpApiController {
|
||||
@RequestPath(value = "/message/send")
|
||||
public HttpResponse chat(HttpRequest request, HttpConfig httpConfig, ChannelContext channelContext)throws Exception {
|
||||
HttpResponse response = new HttpResponse(request,httpConfig);
|
||||
ImPacket chatPacket = new ChatReqHandler().handler(request, channelContext);
|
||||
ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ,ChatReqHandler.class);
|
||||
ImPacket chatPacket = chatReqHandler.handler(request, channelContext);
|
||||
if(chatPacket != null){
|
||||
response = (HttpResponse)chatPacket;
|
||||
}
|
||||
@ -49,8 +51,8 @@ public class HttpApiController {
|
||||
if(params == null || params.length == 0){
|
||||
return HttpResps.json(request, new RespBody(ImStatus.C10020));
|
||||
}
|
||||
String userid = params[0].toString();
|
||||
User user = ImAio.getUser(userid);
|
||||
String userId = params[0].toString();
|
||||
User user = ImAio.getUser(userId);
|
||||
if(user != null){
|
||||
return HttpResps.json(request, new RespBody(ImStatus.C10019));
|
||||
}else{
|
||||
@ -71,9 +73,10 @@ public class HttpApiController {
|
||||
if(params == null || params.length == 0){
|
||||
return HttpResps.json(request, new RespBody(ImStatus.C10020));
|
||||
}
|
||||
String userid = params[0].toString();
|
||||
ImPacket closePacket = new ImPacket(Command.COMMAND_CLOSE_REQ,new CloseReqBody(userid).toByte());
|
||||
new CloseReqHandler().handler(closePacket, channelContext);
|
||||
String userId = params[0].toString();
|
||||
ImPacket closePacket = new ImPacket(Command.COMMAND_CLOSE_REQ,new CloseReqBody(userId).toByte());
|
||||
CloseReqHandler closeReqHandler = CommandManager.getCommand(Command.COMMAND_CLOSE_REQ,CloseReqHandler.class);
|
||||
closeReqHandler.handler(closePacket, channelContext);
|
||||
return HttpResps.json(request, new RespBody(ImStatus.C10021));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user