优化代码规范

This commit is contained in:
wangchao 2018-09-06 00:58:55 +08:00
parent f18fae7026
commit da7f2af79d
31 changed files with 402 additions and 542 deletions

View File

@ -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
* @authorWChao 创建时间: 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获取当前用户所在通道集合]
* @authorWChao 创建时间: 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
*
* 功能描述[获取所有用户(在线+离线)]
* @authorWChao 创建时间: 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
*
* 功能描述[获取所有在线用户]
* @authorWChao 创建时间: 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
* @authorWChao 创建时间: 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){

View File

@ -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;
}
}

View File

@ -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;
/**
* 通道所属协议处理器;
*/

View File

@ -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);
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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"));
}

View File

@ -22,7 +22,7 @@ public class SubRunnable implements Runnable {
}
this.subChannel = subChannel;
}
@Override
public void run() {
log.debug("订阅 redis , chanel {} , 线程将阻塞",subChannel);
while(true){

View File

@ -162,6 +162,11 @@ public class Config {
}
public interface Builder {
/**
* 配置构建接口
* @return
* @throws Exception
*/
Config build() throws Exception;
}
}

View File

@ -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;

View File

@ -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"));

View File

@ -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{
* 示例
* 1classpath中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;
}
}

View File

@ -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){

View File

@ -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;
// }
}

View File

@ -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

View File

@ -125,6 +125,7 @@ public class HttpResponse extends HttpPacket {
/**
* @return the status
*/
@Override
public HttpResponseStatus getStatus() {
return status;
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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 :httpwstcp等
*/
public String name();
/**
* 判断是否属于指定协议
* @param imPacket
* @param channelContext
* @return
* @throws Throwable
*/
public boolean isProtocol(ImPacket imPacket,ChannelContext channelContext)throws Throwable;
/**
* 获取该协议包转化器
* @return
*/
public IConvertProtocolPacket converter();
}

View File

@ -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){

View File

@ -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++;

View File

@ -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);

View File

@ -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);

View File

@ -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
*
* 功能描述[转换不同协议响应包]
* @authorWChao 创建时间: 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
*
* 功能描述[转换不同协议响应包]
* @authorWChao 创建时间: 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()));
}
/**
* 获取所有协议判断器目前内置(HttpProtocolWebsocketProtocolHttpProtocol)
* 获取所有协议判断器目前内置(HttpProtocolWebSocketProtocolHttpProtocol)
* @return
*/
public static Map<String, AbProtocol> getProtocols() {
@ -154,63 +158,68 @@ public class ImKit {
}
/**
* 复制用户信息不包括friedsgroups下的users信息;
* 复制用户信息不包括friendsgroups下的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;
}
/**
* 复制用户信息不包括friedsgroups下的users信息;
* 复制用户信息不包括friendsgroups下的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;
}
}

View File

@ -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));

View File

@ -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){

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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证书哦...)

View File

@ -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));
}
}