114 changed files with 1112 additions and 901 deletions
@ -1,18 +1,32 @@ |
|||
package com.bx.imcommon.contant; |
|||
|
|||
public class IMRedisKey { |
|||
public final class IMRedisKey { |
|||
|
|||
// im-server最大id,从0开始递增
|
|||
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"; |
|||
// 未读私聊消息队列
|
|||
public final static String IM_MESSAGE_PRIVATE_QUEUE = "im:message:private"; |
|||
// 未读群聊消息队列
|
|||
public final static String IM_MESSAGE_GROUP_QUEUE = "im:message:group"; |
|||
// 私聊消息发送结果队列
|
|||
public final static String IM_RESULT_PRIVATE_QUEUE = "im:result:private"; |
|||
// 群聊消息发送结果队列
|
|||
public final static String IM_RESULT_GROUP_QUEUE = "im:result:group"; |
|||
private IMRedisKey() {} |
|||
|
|||
/** |
|||
* im-server最大id,从0开始递增 |
|||
*/ |
|||
public static final String IM_MAX_SERVER_ID = "im:max_server_id"; |
|||
/** |
|||
* 用户ID所连接的IM-server的ID |
|||
*/ |
|||
public static final String IM_USER_SERVER_ID = "im:user:server_id"; |
|||
/** |
|||
* 未读私聊消息队列 |
|||
*/ |
|||
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; |
|||
|
|||
public final class Constant { |
|||
|
|||
public class Constant { |
|||
// 最大图片上传大小
|
|||
public static final long MAX_IMAGE_SIZE = 5*1024*1024; |
|||
// 最大上传文件大小
|
|||
public static final long MAX_FILE_SIZE = 10*1024*1024; |
|||
// 群聊最大人数
|
|||
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_GROUP_MEMBER = 500; |
|||
|
|||
|
|||
} |
|||
|
|||
@ -1,18 +1,33 @@ |
|||
package com.bx.implatform.contant; |
|||
|
|||
public class RedisKey { |
|||
public final class RedisKey { |
|||
|
|||
// 已读群聊消息位置(已读最大id)
|
|||
public final static String IM_GROUP_READED_POSITION = "im:readed:group:position"; |
|||
// webrtc 会话信息
|
|||
public final static String IM_WEBRTC_SESSION = "im:webrtc:session"; |
|||
// 缓存前缀
|
|||
public final static String IM_CACHE = "im:cache:"; |
|||
// 缓存是否好友:bool
|
|||
public final static String IM_CACHE_FRIEND = IM_CACHE+"friend"; |
|||
// 缓存群聊信息
|
|||
public final static String IM_CACHE_GROUP = IM_CACHE+"group"; |
|||
// 缓存群聊成员id
|
|||
public final static String IM_CACHE_GROUP_MEMBER_ID = IM_CACHE+"group_member_ids"; |
|||
private RedisKey() { |
|||
} |
|||
|
|||
/** |
|||
* 已读群聊消息位置(已读最大id) |
|||
*/ |
|||
public static final String IM_GROUP_READED_POSITION = "im:readed:group:position"; |
|||
/** |
|||
* webrtc 会话信息 |
|||
*/ |
|||
public static final String IM_WEBRTC_SESSION = "im:webrtc:session"; |
|||
/** |
|||
* 缓存前缀 |
|||
*/ |
|||
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; |
|||
|
|||
|
|||
import com.bx.implatform.enums.ResultCode; |
|||
|
|||
public class ResultUtils { |
|||
public final class ResultUtils { |
|||
|
|||
private ResultUtils() { |
|||
} |
|||
|
|||
public static <T> Result<T> success(){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> success() { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(ResultCode.SUCCESS.getCode()); |
|||
result.setMessage(ResultCode.SUCCESS.getMsg()); |
|||
return result; |
|||
} |
|||
|
|||
public static <T> Result<T> success(T data){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> success(T data) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(ResultCode.SUCCESS.getCode()); |
|||
result.setMessage(ResultCode.SUCCESS.getMsg()); |
|||
result.setData(data); |
|||
return result; |
|||
} |
|||
|
|||
public static <T> Result<T> success(T data, String messsage){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> success(T data, String messsage) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(ResultCode.SUCCESS.getCode()); |
|||
result.setMessage(messsage); |
|||
result.setData(data); |
|||
return result; |
|||
} |
|||
|
|||
public static <T> Result<T> success(String messsage){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> success(String messsage) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(ResultCode.SUCCESS.getCode()); |
|||
result.setMessage(messsage); |
|||
return result; |
|||
} |
|||
|
|||
public static <T> Result<T> error(Integer code, String messsage){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> error(Integer code, String messsage) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(code); |
|||
result.setMessage(messsage); |
|||
return result; |
|||
} |
|||
|
|||
|
|||
public static <T> Result<T> error(ResultCode resultCode, String messsage){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> error(ResultCode resultCode, String messsage) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(resultCode.getCode()); |
|||
result.setMessage(messsage); |
|||
return result; |
|||
} |
|||
|
|||
public static <T> Result<T> error(ResultCode resultCode){ |
|||
Result<T> result=new Result<>(); |
|||
public static <T> Result<T> error(ResultCode resultCode) { |
|||
Result<T> result = new Result<>(); |
|||
result.setCode(resultCode.getCode()); |
|||
result.setMessage(resultCode.getMsg()); |
|||
return result; |
|||
} |
|||
|
|||
|
|||
|
|||
} |
|||
|
|||
@ -1,42 +1,45 @@ |
|||
package com.bx.implatform.util; |
|||
|
|||
import org.springframework.util.ReflectionUtils; |
|||
|
|||
public final class BeanUtils { |
|||
|
|||
private BeanUtils() { |
|||
} |
|||
|
|||
private static void handleReflectionException(Exception e) { |
|||
ReflectionUtils.handleReflectionException(e); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 属性拷贝 |
|||
* |
|||
* @param orig 源对象 |
|||
* @param destClass 目标 |
|||
* @return T |
|||
*/ |
|||
public static <T> T copyProperties(Object orig, Class<T> destClass) { |
|||
try { |
|||
T target = destClass.newInstance(); |
|||
if (orig == null) { |
|||
return null; |
|||
} |
|||
copyProperties(orig, target); |
|||
return target; |
|||
} catch (Exception e) { |
|||
handleReflectionException(e); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
|
|||
public class BeanUtils { |
|||
|
|||
|
|||
private static void handleReflectionException(Exception e) { |
|||
ReflectionUtils.handleReflectionException(e); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 属性拷贝 |
|||
* @param orig 源对象 |
|||
* @param destClass 目标 |
|||
* @return T |
|||
*/ |
|||
public static <T> T copyProperties(Object orig, Class<T> destClass) { |
|||
try { |
|||
Object target = destClass.newInstance(); |
|||
if(orig == null) { |
|||
return null; |
|||
} |
|||
copyProperties(orig, target); |
|||
return (T) 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) { |
|||
handleReflectionException(e); |
|||
} |
|||
} |
|||
public static void copyProperties(Object orig, Object dest) { |
|||
try { |
|||
org.springframework.beans.BeanUtils.copyProperties(orig, dest); |
|||
} catch (Exception e) { |
|||
handleReflectionException(e); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,22 +1,19 @@ |
|||
package com.bx.imserver; |
|||
|
|||
|
|||
import org.springframework.boot.SpringApplication; |
|||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
|||
import org.springframework.context.annotation.ComponentScan; |
|||
import org.springframework.scheduling.annotation.EnableAsync; |
|||
import org.springframework.scheduling.annotation.EnableScheduling; |
|||
|
|||
|
|||
@EnableAsync |
|||
@EnableScheduling |
|||
@ComponentScan(basePackages={"com.bx"}) |
|||
@ComponentScan(basePackages = {"com.bx"}) |
|||
@SpringBootApplication |
|||
public class IMServerApp { |
|||
|
|||
|
|||
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; |
|||
|
|||
public class ChannelAttrKey { |
|||
public final class ChannelAttrKey { |
|||
|
|||
// 用户ID
|
|||
private ChannelAttrKey() { |
|||
} |
|||
|
|||
/** |
|||
* 用户ID |
|||
*/ |
|||
public static final String USER_ID = "USER_ID"; |
|||
// 终端类型
|
|||
/** |
|||
* 终端类型 |
|||
*/ |
|||
public static final String TERMINAL_TYPE = "TERMINAL_TYPE"; |
|||
// 心跳次数
|
|||
/** |
|||
* 心跳次数 |
|||
*/ |
|||
public static final String HEARTBEAT_TIMES = "HEARTBEAt_TIMES"; |
|||
|
|||
} |
|||
|
|||
@ -1,17 +1,18 @@ |
|||
package com.bx.imserver.netty.processor; |
|||
|
|||
|
|||
import io.netty.channel.ChannelHandlerContext; |
|||
|
|||
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){ |
|||
return (T)o; |
|||
} |
|||
public T transForm(Object o) { |
|||
return (T) o; |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue