114 changed files with 1112 additions and 901 deletions
@ -1,18 +1,32 @@ |
|||||
package com.bx.imcommon.contant; |
package com.bx.imcommon.contant; |
||||
|
|
||||
public class IMRedisKey { |
public final class IMRedisKey { |
||||
|
|
||||
// im-server最大id,从0开始递增
|
private IMRedisKey() {} |
||||
public final static String IM_MAX_SERVER_ID = "im:max_server_id"; |
|
||||
// 用户ID所连接的IM-server的ID
|
/** |
||||
public final static String IM_USER_SERVER_ID = "im:user:server_id"; |
* im-server最大id,从0开始递增 |
||||
// 未读私聊消息队列
|
*/ |
||||
public final static String IM_MESSAGE_PRIVATE_QUEUE = "im:message:private"; |
public static final String IM_MAX_SERVER_ID = "im:max_server_id"; |
||||
// 未读群聊消息队列
|
/** |
||||
public final static String IM_MESSAGE_GROUP_QUEUE = "im:message:group"; |
* 用户ID所连接的IM-server的ID |
||||
// 私聊消息发送结果队列
|
*/ |
||||
public final static String IM_RESULT_PRIVATE_QUEUE = "im:result:private"; |
public static final String IM_USER_SERVER_ID = "im:user:server_id"; |
||||
// 群聊消息发送结果队列
|
/** |
||||
public final static String IM_RESULT_GROUP_QUEUE = "im:result:group"; |
* 未读私聊消息队列 |
||||
|
*/ |
||||
|
public static final String IM_MESSAGE_PRIVATE_QUEUE = "im:message:private"; |
||||
|
/** |
||||
|
* 未读群聊消息队列 |
||||
|
*/ |
||||
|
public static final String IM_MESSAGE_GROUP_QUEUE = "im:message:group"; |
||||
|
/** |
||||
|
* 私聊消息发送结果队列 |
||||
|
*/ |
||||
|
public static final String IM_RESULT_PRIVATE_QUEUE = "im:result:private"; |
||||
|
/** |
||||
|
* 群聊消息发送结果队列 |
||||
|
*/ |
||||
|
public static final String IM_RESULT_GROUP_QUEUE = "im:result:group"; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,100 @@ |
|||||
|
package com.bx.imcommon.util; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
|
||||
|
import java.util.concurrent.LinkedBlockingQueue; |
||||
|
import java.util.concurrent.ThreadPoolExecutor; |
||||
|
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
/** |
||||
|
* 创建单例线程池 |
||||
|
* @author Andrews |
||||
|
* @date 2023/11/30 11:12 |
||||
|
*/ |
||||
|
public final class ThreadPoolExecutorFactory { |
||||
|
/** |
||||
|
* 机器的CPU核数:Runtime.getRuntime().availableProcessors() |
||||
|
* corePoolSize 池中所保存的线程数,包括空闲线程。 |
||||
|
* CPU 密集型:核心线程数 = CPU核数 + 1 |
||||
|
* IO 密集型:核心线程数 = CPU核数 * 2 |
||||
|
*/ |
||||
|
private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2; |
||||
|
/** |
||||
|
* maximumPoolSize - 池中允许的最大线程数(采用LinkedBlockingQueue时没有作用)。 |
||||
|
*/ |
||||
|
private static final int MAX_IMUM_POOL_SIZE = 100; |
||||
|
/** |
||||
|
* keepAliveTime -当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间,线程池维护线程所允许的空闲时间 |
||||
|
*/ |
||||
|
private static final int KEEP_ALIVE_TIME = 1000; |
||||
|
/** |
||||
|
* 等待队列的大小。默认是无界的,性能损耗的关键 |
||||
|
*/ |
||||
|
private static final int QUEUE_SIZE = 200; |
||||
|
|
||||
|
/** |
||||
|
* 线程池对象 |
||||
|
*/ |
||||
|
private static volatile ThreadPoolExecutor threadPoolExecutor = null; |
||||
|
|
||||
|
/** |
||||
|
* 构造方法私有化 |
||||
|
*/ |
||||
|
private ThreadPoolExecutorFactory() { |
||||
|
if (null == threadPoolExecutor) { |
||||
|
threadPoolExecutor = ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 重写readResolve方法 |
||||
|
*/ |
||||
|
private Object readResolve() { |
||||
|
//重写readResolve方法,防止序列化破坏单例
|
||||
|
return ThreadPoolExecutorFactory.getThreadPoolExecutor(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 双检锁创建线程安全的单例 |
||||
|
*/ |
||||
|
public static ThreadPoolExecutor getThreadPoolExecutor() { |
||||
|
if (null == threadPoolExecutor) { |
||||
|
synchronized (ThreadPoolExecutorFactory.class) { |
||||
|
if (null == threadPoolExecutor) { |
||||
|
threadPoolExecutor = new ThreadPoolExecutor( |
||||
|
//核心线程数
|
||||
|
CORE_POOL_SIZE, |
||||
|
//最大线程数,包含临时线程
|
||||
|
MAX_IMUM_POOL_SIZE, |
||||
|
//临时线程的存活时间
|
||||
|
KEEP_ALIVE_TIME, |
||||
|
//时间单位(毫秒)
|
||||
|
TimeUnit.MILLISECONDS, |
||||
|
//等待队列
|
||||
|
new LinkedBlockingQueue<>(QUEUE_SIZE), |
||||
|
//拒绝策略
|
||||
|
new ThreadPoolExecutor.CallerRunsPolicy() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return threadPoolExecutor; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 关闭线程池 |
||||
|
*/ |
||||
|
public void shutDown() { |
||||
|
if (threadPoolExecutor != null) { |
||||
|
threadPoolExecutor.shutdown(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public void execute(Runnable runnable) { |
||||
|
if (runnable == null) { |
||||
|
return; |
||||
|
} |
||||
|
threadPoolExecutor.execute(runnable); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -1,12 +1,21 @@ |
|||||
package com.bx.implatform.contant; |
package com.bx.implatform.contant; |
||||
|
|
||||
|
public final class Constant { |
||||
|
|
||||
public class Constant { |
private Constant() { |
||||
// 最大图片上传大小
|
} |
||||
public static final long MAX_IMAGE_SIZE = 5*1024*1024; |
|
||||
// 最大上传文件大小
|
/** |
||||
public static final long MAX_FILE_SIZE = 10*1024*1024; |
* 最大图片上传大小 |
||||
// 群聊最大人数
|
*/ |
||||
|
public static final long MAX_IMAGE_SIZE = 5 * 1024 * 1024; |
||||
|
/** |
||||
|
* 最大上传文件大小 |
||||
|
*/ |
||||
|
public static final long MAX_FILE_SIZE = 10 * 1024 * 1024; |
||||
|
/** |
||||
|
* 群聊最大人数 |
||||
|
*/ |
||||
public static final long MAX_GROUP_MEMBER = 500; |
public static final long MAX_GROUP_MEMBER = 500; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,18 +1,33 @@ |
|||||
package com.bx.implatform.contant; |
package com.bx.implatform.contant; |
||||
|
|
||||
public class RedisKey { |
public final class RedisKey { |
||||
|
|
||||
// 已读群聊消息位置(已读最大id)
|
private RedisKey() { |
||||
public final static String IM_GROUP_READED_POSITION = "im:readed:group:position"; |
} |
||||
// webrtc 会话信息
|
|
||||
public final static String IM_WEBRTC_SESSION = "im:webrtc:session"; |
/** |
||||
// 缓存前缀
|
* 已读群聊消息位置(已读最大id) |
||||
public final static String IM_CACHE = "im:cache:"; |
*/ |
||||
// 缓存是否好友:bool
|
public static final String IM_GROUP_READED_POSITION = "im:readed:group:position"; |
||||
public final static String IM_CACHE_FRIEND = IM_CACHE+"friend"; |
/** |
||||
// 缓存群聊信息
|
* webrtc 会话信息 |
||||
public final static String IM_CACHE_GROUP = IM_CACHE+"group"; |
*/ |
||||
// 缓存群聊成员id
|
public static final String IM_WEBRTC_SESSION = "im:webrtc:session"; |
||||
public final static String IM_CACHE_GROUP_MEMBER_ID = IM_CACHE+"group_member_ids"; |
/** |
||||
|
* 缓存前缀 |
||||
|
*/ |
||||
|
public static final String IM_CACHE = "im:cache:"; |
||||
|
/** |
||||
|
* 缓存是否好友:bool |
||||
|
*/ |
||||
|
public static final String IM_CACHE_FRIEND = IM_CACHE + "friend"; |
||||
|
/** |
||||
|
* 缓存群聊信息 |
||||
|
*/ |
||||
|
public static final String IM_CACHE_GROUP = IM_CACHE + "group"; |
||||
|
/** |
||||
|
* 缓存群聊成员id |
||||
|
*/ |
||||
|
public static final String IM_CACHE_GROUP_MEMBER_ID = IM_CACHE + "group_member_ids"; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,62 +1,63 @@ |
|||||
package com.bx.implatform.result; |
package com.bx.implatform.result; |
||||
|
|
||||
|
|
||||
import com.bx.implatform.enums.ResultCode; |
import com.bx.implatform.enums.ResultCode; |
||||
|
|
||||
public class ResultUtils { |
public final class ResultUtils { |
||||
|
|
||||
|
private ResultUtils() { |
||||
|
} |
||||
|
|
||||
public static <T> Result<T> success(){ |
public static <T> Result<T> success() { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(ResultCode.SUCCESS.getCode()); |
result.setCode(ResultCode.SUCCESS.getCode()); |
||||
result.setMessage(ResultCode.SUCCESS.getMsg()); |
result.setMessage(ResultCode.SUCCESS.getMsg()); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
public static <T> Result<T> success(T data){ |
public static <T> Result<T> success(T data) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(ResultCode.SUCCESS.getCode()); |
result.setCode(ResultCode.SUCCESS.getCode()); |
||||
result.setMessage(ResultCode.SUCCESS.getMsg()); |
result.setMessage(ResultCode.SUCCESS.getMsg()); |
||||
result.setData(data); |
result.setData(data); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
public static <T> Result<T> success(T data, String messsage){ |
public static <T> Result<T> success(T data, String messsage) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(ResultCode.SUCCESS.getCode()); |
result.setCode(ResultCode.SUCCESS.getCode()); |
||||
result.setMessage(messsage); |
result.setMessage(messsage); |
||||
result.setData(data); |
result.setData(data); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
public static <T> Result<T> success(String messsage){ |
public static <T> Result<T> success(String messsage) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(ResultCode.SUCCESS.getCode()); |
result.setCode(ResultCode.SUCCESS.getCode()); |
||||
result.setMessage(messsage); |
result.setMessage(messsage); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
public static <T> Result<T> error(Integer code, String messsage){ |
public static <T> Result<T> error(Integer code, String messsage) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(code); |
result.setCode(code); |
||||
result.setMessage(messsage); |
result.setMessage(messsage); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
|
|
||||
public static <T> Result<T> error(ResultCode resultCode, String messsage){ |
public static <T> Result<T> error(ResultCode resultCode, String messsage) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(resultCode.getCode()); |
result.setCode(resultCode.getCode()); |
||||
result.setMessage(messsage); |
result.setMessage(messsage); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
public static <T> Result<T> error(ResultCode resultCode){ |
public static <T> Result<T> error(ResultCode resultCode) { |
||||
Result<T> result=new Result<>(); |
Result<T> result = new Result<>(); |
||||
result.setCode(resultCode.getCode()); |
result.setCode(resultCode.getCode()); |
||||
result.setMessage(resultCode.getMsg()); |
result.setMessage(resultCode.getMsg()); |
||||
return result; |
return result; |
||||
} |
} |
||||
|
|
||||
|
|
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,42 +1,45 @@ |
|||||
package com.bx.implatform.util; |
package com.bx.implatform.util; |
||||
import org.springframework.util.ReflectionUtils; |
|
||||
|
|
||||
|
import org.springframework.util.ReflectionUtils; |
||||
|
|
||||
public class BeanUtils { |
public final class BeanUtils { |
||||
|
|
||||
|
private BeanUtils() { |
||||
private static void handleReflectionException(Exception e) { |
} |
||||
ReflectionUtils.handleReflectionException(e); |
|
||||
} |
private static void handleReflectionException(Exception e) { |
||||
|
ReflectionUtils.handleReflectionException(e); |
||||
|
} |
||||
/** |
|
||||
* 属性拷贝 |
|
||||
* @param orig 源对象 |
/** |
||||
* @param destClass 目标 |
* 属性拷贝 |
||||
* @return T |
* |
||||
*/ |
* @param orig 源对象 |
||||
public static <T> T copyProperties(Object orig, Class<T> destClass) { |
* @param destClass 目标 |
||||
try { |
* @return T |
||||
Object target = destClass.newInstance(); |
*/ |
||||
if(orig == null) { |
public static <T> T copyProperties(Object orig, Class<T> destClass) { |
||||
return null; |
try { |
||||
} |
T target = destClass.newInstance(); |
||||
copyProperties(orig, target); |
if (orig == null) { |
||||
return (T) target; |
return null; |
||||
}catch(Exception e) { |
} |
||||
handleReflectionException(e); |
copyProperties(orig, target); |
||||
return null; |
return target; |
||||
} |
} catch (Exception e) { |
||||
} |
handleReflectionException(e); |
||||
|
return null; |
||||
|
} |
||||
public static void copyProperties(Object orig, Object dest) { |
} |
||||
try { |
|
||||
org.springframework.beans.BeanUtils.copyProperties(orig, dest); |
|
||||
} catch (Exception e) { |
public static void copyProperties(Object orig, Object dest) { |
||||
handleReflectionException(e); |
try { |
||||
} |
org.springframework.beans.BeanUtils.copyProperties(orig, dest); |
||||
} |
} catch (Exception e) { |
||||
|
handleReflectionException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
} |
} |
||||
@ -1,22 +1,19 @@ |
|||||
package com.bx.imserver; |
package com.bx.imserver; |
||||
|
|
||||
|
|
||||
import org.springframework.boot.SpringApplication; |
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.context.annotation.ComponentScan; |
import org.springframework.context.annotation.ComponentScan; |
||||
import org.springframework.scheduling.annotation.EnableAsync; |
import org.springframework.scheduling.annotation.EnableAsync; |
||||
import org.springframework.scheduling.annotation.EnableScheduling; |
import org.springframework.scheduling.annotation.EnableScheduling; |
||||
|
|
||||
|
|
||||
@EnableAsync |
@EnableAsync |
||||
@EnableScheduling |
@EnableScheduling |
||||
@ComponentScan(basePackages={"com.bx"}) |
@ComponentScan(basePackages = {"com.bx"}) |
||||
@SpringBootApplication |
@SpringBootApplication |
||||
public class IMServerApp { |
public class IMServerApp { |
||||
|
|
||||
|
|
||||
public static void main(String[] args) { |
public static void main(String[] args) { |
||||
SpringApplication.run(IMServerApp.class,args); |
SpringApplication.run(IMServerApp.class, args); |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,12 +1,21 @@ |
|||||
package com.bx.imserver.constant; |
package com.bx.imserver.constant; |
||||
|
|
||||
public class ChannelAttrKey { |
public final class ChannelAttrKey { |
||||
|
|
||||
// 用户ID
|
private ChannelAttrKey() { |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 用户ID |
||||
|
*/ |
||||
public static final String USER_ID = "USER_ID"; |
public static final String USER_ID = "USER_ID"; |
||||
// 终端类型
|
/** |
||||
|
* 终端类型 |
||||
|
*/ |
||||
public static final String TERMINAL_TYPE = "TERMINAL_TYPE"; |
public static final String TERMINAL_TYPE = "TERMINAL_TYPE"; |
||||
// 心跳次数
|
/** |
||||
|
* 心跳次数 |
||||
|
*/ |
||||
public static final String HEARTBEAT_TIMES = "HEARTBEAt_TIMES"; |
public static final String HEARTBEAT_TIMES = "HEARTBEAt_TIMES"; |
||||
|
|
||||
} |
} |
||||
|
|||||
@ -1,17 +1,18 @@ |
|||||
package com.bx.imserver.netty.processor; |
package com.bx.imserver.netty.processor; |
||||
|
|
||||
|
|
||||
import io.netty.channel.ChannelHandlerContext; |
import io.netty.channel.ChannelHandlerContext; |
||||
|
|
||||
public abstract class AbstractMessageProcessor<T> { |
public abstract class AbstractMessageProcessor<T> { |
||||
|
|
||||
public void process(ChannelHandlerContext ctx,T data){} |
public void process(ChannelHandlerContext ctx, T data) { |
||||
|
} |
||||
|
|
||||
public void process(T data){} |
public void process(T data) { |
||||
|
} |
||||
|
|
||||
public T transForm(Object o){ |
public T transForm(Object o) { |
||||
return (T)o; |
return (T) o; |
||||
} |
} |
||||
|
|
||||
|
|
||||
} |
} |
||||
|
|||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue