1:webSocket
单机模式下是没办法支撑很多客户端访问的,所以这时候就需要集群部署,但是集群部署也有问题
复制代码
2:解决分布式Session问题
第一:将Session集中管理,比如都放到Redis中
第二:消息分发,比如我现在client-1在app-1发送了一条消息,这时候我只需要将这条消息同步给
app-2,让app-2这个应用推送一下就行,本文采用这种方式
复制代码
3:环境
1: jdk8
2:idea
3:spring-cloud-alibaba
复制代码
4:启动Nacos服务
我下载了Nacos源码包在本地运行,版本是1.4.1
复制代码
5:实现思路
1:用户-1 连接到机器-A,发送一条消息,此时所有连接到机器A的用户都是可以收到这条消息的,就类似于单机一样的
2:此时,在机器A发送这条消息到客户端的时候,我们可以从Naocs拿到该服务的所有实例,这时候只需要调用其它服务的一个接口,将这条消息发送给其它机器
3:当其它机器拿到这条消息之后,就调用WebSocket的方法,将这条消息发送给本机器的所有用户
6:核心代码实现
/**
* 收到客户端消息后调用的方法
*
* @param message
* 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message,Session session) {
log.info("来自客户端的消息:{}",message);
String id = session.getId();
//群发消息,发送给本机器所有的session
BroadCastInfo(id + ":"+message);
try{
log.info("session: {}" ,session);
String uuid = userSession.get(session);
String msg = uuid + "=" + message;
//将消息发送给其它节点的用户
myDiscoveryClient.sendMsgToService(msg);
}catch (Exception e) {
e.printStackTrace();
}
}
复制代码
public void sendMsgToService(String msg) {
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
Map<String,String> params = new HashMap<>();
params.put("msg",msg);
System.out.println("需要发送的消息是: " +msg);
//从Nacos拿到所有的该服务的实例
List<ServiceInstance> instances = discoveryClient.getInstances(SERVICE_ID);
if(instances != null && !instances.isEmpty()) {
for(ServiceInstance instance : instances) {
String host = instance.getHost();
int servicePort = instance.getPort();
log.info("服务器地址:{}:{}",host,servicePort);
String url = "http://socketOne:"+servicePort+"/index/send?msg={msg}";
//如果不是本机器就发送
if(host != addr.getHostAddress()) {
restTemplate.getForObject(url,String.class,params);
}
}
}
}
复制代码
@Resource
private WebSocketServer webSocketServer;
@GetMapping("/send")
@ResponseBody
public String send(@RequestParam("msg") String msg) {
//群发消息
webSocketServer.BroadCastInfo(msg);
return "success";
}
复制代码