package com.zhujizheng.IHome.websocket.server;
import com.zhujizheng.IHome.websocket.Net.Base.NetProtocolBase;
import com.zhujizheng.IHome.websocket.Net.exception.NetException;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created with IntelliJ IDEA
*
* Author: yons
* Date: 2019/04/10
* Time: 02:31
* Description:
* Copyright © 2019年 com.zhujizheng. All rights reserved.
*/
@Slf4j
@ServerEndpoint(value = "/websocket/{sid}")
@Component
public class WebSocketServer {
/** 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。**/
private static int onlineCount = 0;
/** 线程安全Map,用来存放每个客户端对应的WebSocket对象。**/
private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();
public static ConcurrentHashMap getWebSocketMap() {
return webSocketMap;
}
/** 与某个客户端的连接会话,需要通过它来给客户端发送数据 **/
private Session session;
public Session getSession() {
return session;
}
/** 接收sid **/
private String sid="";
public String getSid() {
return sid;
}
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
this.session = session;
// 加入map中
webSocketMap.remove(sid);
webSocketMap.put(sid, this);
// 在线数加1
addOnlineCount();
log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
this.sid = sid;
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
// 从set中删除
webSocketMap.remove(this.sid);
// 在线数减1
subOnlineCount();
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到来自窗口" + sid + "的信息:" + message);
String beat = "py_beat";
if (beat.equals(message)) {
session.getAsyncRemote().sendText(message);
return;
}
NetProtocolBase.dealWithData(message, sid);
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendString(String string) {
System.out.println("服务器主动推送: " + string);
try {
this.session.getBasicRemote().sendText(string);
} catch (IOException e) {
e.printStackTrace();
throw new NetException();
}
}
public static Boolean sendString(String string, @PathParam("sid") String sid) {
if (sid == null) {
System.out.println("sid为空");
return false;
}
log.info("推送消息到窗口"+sid+",推送内容:"+string);
WebSocketServer item = webSocketMap.get(sid);
if (null == item) {
return false;
}
item.sendString(string);
return true;
}
/**
* 群发自定义消息
* */
public void sendInfo(String string, @PathParam("sid") String sid) {
log.info("推送消息到窗口"+sid+",推送内容:"+string);
for(String key : webSocketMap.keySet()){
// 这里可以设定只推送给这个sid的,为null则全部推送
if(sid == null) {
WebSocketServer item = webSocketMap.get(key);
item.sendString(string);
}else if(key.equals(sid)){
WebSocketServer item = webSocketMap.get(key);
item.sendString(string);
}
}
}
private static synchronized int getOnlineCount() {
return onlineCount;
}
private static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
private static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}