redis链接用来推送消息接受消息。mysql用来存在线用户,我尝试过删除 sessionService.add(session);这个存在线用户信息也不影响使用,不影响集群。
最佳实践流程
这个服务端仅开放socket客户端端口,
http端口不开放外网,只给自主应用通过内网调用发消息。这样方便拓展。通讯服务也不需要配置用户登录鉴权,
1.redis配置类
Redis2Config
package com.farsunset.user.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.MapPropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
* @author :Void
* @date :2019-09-17 09:21
* @description:另一个redis的配置
* @version: v1.0.0.23
*/
@Component
@Configuration
@EnableCaching
public class Redis2Config {
//最大活跃数
@Value("${spring.redis2.jedis.pool.max-active:8}")
private int maxActive;
//最大等待数
@Value("${spring.redis2.jedis.pool.max-wait:-1}")
private int maxWait;
//最大核心线程数
@Value("${spring.redis2.jedis.pool.max-idle:8}")
private int maxIdle;
//最小核心线程数
@Value("${spring.redis2.jedis.pool.min-idle:0}")
private int minIdle;
//redis连接的超时时长
@Value("${spring.redis2.timeout:5}")
private int timeOut;
//redis连接的库
@Value("${spring.redis2.database:0}")
private int database;
//节点配置
@Value("${spring.redis2.cluster.nodes:#{null}}")
private String nodes;
//最大连接转移数
@Value("${spring.redis2.cluster.max-redirects:3}")
private int maxRedirects;
//单节点情况下redis的ip
@Value("${spring.redis2.host:#{null}}")
private String host;
//单节点情况下redis的端口
@Value("${spring.redis2.port:#{null}}")
private Integer port;
//redis的连接密码
@Value("${spring.redis2.password:#{null}}")
private String password;
/**
* 创建redisTemplate连接模板
*
* @return
*/
@Primary
@Bean
@Qualifier("redisTemplate2")
public RedisTemplate<String, Object> redisTemplate2() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory2());
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
// om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
// 值采用json序列化
redisTemplate.setValueSerializer(jacksonSeial);
//使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jacksonSeial);
// redisTemplate.setValueSerializer(this.jackson2JsonRedisSerializer2());
redisTemplate.setHashValueSerializer(this.jackson2JsonRedisSerializer2());
return redisTemplate;
}
/**
* k-v的序列化
*
* @return
*/
@Bean
public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer2() {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
/**
* 连接配置
*
* @return
*/
@Primary
@Bean
public RedisConnectionFactory connectionFactory2() {
Map<String, Object> source = new HashMap<String, Object>();
RedisClusterConfiguration redisClusterConfiguration;
RedisStandaloneConfiguration redisStandaloneConfiguration;
//连接池配置
GenericObjectPoolConfig genericObjectPoolConfig =
new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxTotal(maxActive);
genericObjectPoolConfig.setMaxWaitMillis(maxWait);
genericObjectPoolConfig.setMaxIdle(maxIdle);
genericObjectPoolConfig.setMinIdle(minIdle);
//redis客户端配置
LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
builder = LettucePoolingClientConfiguration.builder().
commandTimeout(Duration.ofSeconds(timeOut));
builder.poolConfig(genericObjectPoolConfig);
LettuceClientConfiguration lettuceClientConfiguration = builder.build();
//集群模式
if(nodes !=null){
source.put("spring.redis.cluster.nodes", nodes);
source.put("spring.redis.cluster.max-redirects", maxRedirects);
redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
if(password!=null && !password.equals("")){
redisClusterConfiguration.setPassword(password);
}
//根据配置和客户端配置创建连接工厂
LettuceConnectionFactory lettuceConnectionFactory = new
LettuceConnectionFactory(redisClusterConfiguration,lettuceClientConfiguration);
// lettuceConnectionFactory .afterPropertiesSet();
return lettuceConnectionFactory;
}else{
//单机模式
redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port);
redisStandaloneConfiguration.setDatabase(database);
if(password!=null && !password.equals("")){
redisStandaloneConfiguration.setPassword(password);
}
//根据配置和客户端配置创建连接
LettuceConnectionFactory lettuceConnectionFactory = new
LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration);
// lettuceConnectionFactory .afterPropertiesSet();
return lettuceConnectionFactory;
}
}
}
2.redis 工具类
RedisUtil2
package com.farsunset.user.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* redis缓存调用的Java方法
* @author chenlinyan
* @date 2019/5/25 11:34
* @description:RedisTemplate会自动装配
* @version v2.0.0
* @see {@link org.springframework.boot.autoconfigure.data.redis}
*/
@Slf4j
@Component
public class RedisUtil2 {
@Autowired
@Qualifier("redisTemplate2")
// private RedisTemplate<Object, Object> redisTemplate;
private RedisTemplate redisTemplate;
// private RedisTemplate<Object, Object> redisTemplate;
@Value("${jwt.online-key}")
private String onlineKey;
public RedisUtil2(RedisTemplate<Object, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
// =============================commonold============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据 key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(Object key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 查找匹配key
* @param pattern key
* @return /
*/
public List<String> scan(String pattern) {
ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor<byte[]> cursor = rc.scan(options);
List<String> result = new ArrayList<>();
while (cursor.hasNext()) {
result.add(new String(cursor.next()));
}
try {
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 分页查询 key
* @param patternKey key
* @param page 页码
* @param size 每页数目
* @return /
*/
public List<String> findKeysForPage(String patternKey, int page, int size) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor<byte[]> cursor = rc.scan(options);
List<String> result = new ArrayList<>(size);
int tmpIndex = 0;
int fromIndex = page * size;
int toIndex = page * size + size;
while (cursor.hasNext()) {
if (tmpIndex >= fromIndex && tmpIndex < toIndex) {
result.add(new String(cursor.next()));
tmpIndex++;
continue;
}
// 获取到满足条件的数据后,就可以退出了
if(tmpIndex >=toIndex) {
break;
}
tmpIndex++;
cursor.next();
}
try {
RedisConnectionUtils.releaseConnection(rc, factory);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public String getY(String key){
return key == null || !redisTemplate.hasKey(key) ? "" : redisTemplate.opsForValue().get(key).toString();
}
/**
* 批量获取
* @param keys
* @return
*/
public List<Object> multiGet(List<String> keys) {
Object obj = redisTemplate.opsForValue().multiGet(Collections.singleton(keys));
return null;
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间
* @param timeUnit 类型
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time, TimeUnit timeUnit) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, timeUnit);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// ================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return /
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
return redisTemplate.opsForList().remove(key, count, value);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
- 客户端建立ws链接 鉴权类修改
com.farsunset.cim.component.handler.BindHandler
/*
* Copyright 2013-2019 Xia Jun(3979434@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************************
* *
* Website : http://www.farsunset.com *
* *
***************************************************************************************
*/
package com.farsunset.cim.component.handler;
//import co.yixiang.modules.user.vo.OnlineUser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.farsunset.cim.sdk.server.constant.ChannelAttr;
import com.farsunset.cim.sdk.server.group.SessionGroup;
import com.farsunset.cim.sdk.server.handler.CIMRequestHandler;
import com.farsunset.cim.sdk.server.model.ReplyBody;
import com.farsunset.cim.sdk.server.model.SentBody;
import com.farsunset.cim.component.handler.annotation.CIMHandler;
import com.farsunset.cim.component.redis.SignalRedisTemplate;
import com.farsunset.cim.entity.Session;
import com.farsunset.cim.service.SessionService;
import com.farsunset.user.utils.RedisUtil2;
import io.netty.channel.Channel;
import org.springframework.http.HttpStatus;
import javax.annotation.Resource;
/**
* 客户长连接 账户绑定实现
*/
@CIMHandler(key = "client_bind")
public class BindHandler implements CIMRequestHandler {
@Resource
private SessionService sessionService;
@Resource
private SessionGroup sessionGroup;
@Resource
private SignalRedisTemplate signalRedisTemplate;
@Resource
private RedisUtil2 redis2Util;
@Override
public void process(Channel channel, SentBody body) {
ReplyBody reply = new ReplyBody();
reply.setKey(body.getKey());
reply.setCode(HttpStatus.OK.value());
reply.setTimestamp(System.currentTimeMillis());
#用户建立链接 传过来的token 前段js测试类传的是uid 把uid改成token
String token = body.get("token");
Object obj = redis2Util.get("app-online-token:" + token);
Session session = new Session();
String uid = null;
if (obj != null) {
// Feature.DisableSpecialKeyDetect 序列化参数 防止@type关键字报错
JSONObject json = JSON.parseObject(JSONObject.toJSONString(obj), Feature.DisableSpecialKeyDetect);
// 删除序列化关键字 防止转换报错
json.remove("@type");
// OnlineUser user = JSON.toJavaObject(json, OnlineUser.class);
uid = json.get("uid").toString();
}else {
uid = body.get("uid");
}
if(uid==null){
return;
}
session.setUid(uid);
// String uid = body.get("uid");
session.setNid(channel.attr(ChannelAttr.ID).get());
session.setDeviceId(body.get("deviceId"));
session.setChannel(body.get("channel"));
session.setDeviceName(body.get("deviceName"));
session.setAppVersion(body.get("appVersion"));
session.setOsVersion(body.get("osVersion"));
session.setLanguage(body.get("language"));
channel.attr(ChannelAttr.UID).set(uid);
channel.attr(ChannelAttr.CHANNEL).set(session.getChannel());
channel.attr(ChannelAttr.DEVICE_ID).set(session.getDeviceId());
channel.attr(ChannelAttr.LANGUAGE).set(session.getLanguage());
/*
*存储到数据库
*/
sessionService.add(session);
/*
* 添加到内存管理
*/
sessionGroup.add(channel);
/*
*向客户端发送bind响应
*/
channel.writeAndFlush(reply);
/*
* 发送上线事件到集群中的其他实例,控制其他设备下线
*/
signalRedisTemplate.bind(session);
}
}
application.xml
server:
port: 80
servlet:
context-path: /
# context-path: /api
encoding:
charset: UTF-8
enabled: true
force: true
tomcat:
uri-encoding: UTF-8
spring:
profiles:
active: dev
jackson:
time-zone: GMT+8
data:
redis:
repositories:
enabled: false
# # JDBC Config #
# ##################################################################
datasource:
url: jdbc:mysql://81.70.39.12:3306/cim?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: cim
password: 3ryEHntM4Fsk7G48
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
maximum-pool-size: 10
auto-commit: true
idle-timeout: 30000
pool-name: MASTER_HIKARI_POOL
max-lifetime: 120000
connection-timeout: 30000
connection-test-query: SELECT 1
validation-timeout: 600000
##################################################################
# JPA Config #
##################################################################
jpa:
database: MYSQL
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.ddl-auto: update
open-in-view: false
hibernate.naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
hibernate.naming.physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# #################################################################
# Freemarker Config #
# #################################################################
freemarker:
check-template-location: false
suffix: .html
charset: utf-8
content-type: text/html
cache: false
templateLoaderPath: classpath:/page/
settings.auto_import: /ftl/spring.ftl as spring
messages:
encoding: UTF-8
basename: i18n/messages
##################################################################
# userInfo token Redis Config 和应用redis相同,获取登录信息 #
##################################################################
redis2:
host: 8.11.31.155
database: 14
port: 6379
password: foobxxxxvby,.ewpcx
timeout: 5
jedis:
pool:
max-active: 50
max-wait: 5
max-idle: 50
min-idle: 0
##################################################################
# Redis Config 通讯redis,缓存用户链接信息 #
##################################################################
redis:
host: 8.11.1.155 # Redis服务器地址
database: 14 # Redis数据库索引(默认为0)
port: 6379 # Redis服务器连接端口
password: foobaxxxewpcx # Redis服务器连接密码(默认为空)
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 3000ms # 连接超时时间(毫秒)
mybatis-plus:
check-config-location: true
configuration:
map-underscore-to-camel-case: true
global-config:
db-config:
id-type: auto
logic-delete-value: 1
logic-not-delete-value: 0
# mapper-locations: classpath*:mapper/**/*Mapper.xml
jwt:
header: Authorization
# 令牌前缀
token-start-with: Bearer
online-key: yshopapp
cim:
app:
port: 23456
websocket:
port: 34567
apns:
app-id: com.xxx.xxx.ios
debug: false
p12:
file: /apns/app.p12
password: 123
mysql 用阿里驱动配置如下
datasource:
druid:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://rm-8vbif77yv6gb1p4g7jo.mysql.zhangbei.rds.aliyuncs.com:3306/b2ddb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
username: bfd
password: ekcxc9jddy@byj
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: admin
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
pom
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>








网友评论