1、springboot集成:
项目中使用的socket案例如下:
服务端代码示例:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hwd.wisdomcloud.common.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 其他地方调用时方法:
* WebSocket ws = new WebSocket();
* JSONObject jo = new JSONObject();
* jo.put("message", "这是后台返回的消息!");
* jo.put("To",invIO.getIoEmployeeUid());
* ws.onMessage(jo.toString());
*
*/
@ServerEndpoint("/school_dorm_websocket/{screen_id}/")
@Component
@Slf4j
public class DormitoryScreenWebSocket {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static int onlineCount = 0;
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
public static List<DormitoryScreenWebSocket> webSocketSet = new ArrayList<>();
/**
* 存放所有连接人信息
* */
public static List<String> screenList = new ArrayList<>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 用户ID
*/
public String screenId = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("screen_id") String screenId) {
this.session = session;
this.screenId = screenId;
this.screenList.add( screenId ) ;
//加入set中
webSocketSet.add(this);
//在线数加1
addOnlineCount();
log.info("有新连接加入设备参数设置服务端!" + screenId + "当前在线大屏数为" + getOnlineCount());
JSONObject msg = new JSONObject();
try {
msg.put("msg", "连接成功");
msg.put("status", "SUCCESS");
msg.put("screenId", screenId);
sendMessage(JSON.toJSONString(msg));
} catch (Exception e) {
log.debug("IO异常");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(@PathParam("screen_id") String screenId ) {
//从set中删除
webSocketSet.remove(this);
subOnlineCount();
log.info("有一连接从设备参数"+ screenId +"设置服务端关闭!当前在线大屏数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, @PathParam("screen_id") String screenId ) {
log.info("来自客户端" + screenId + "的消息:" + message);
//发消息给指定用户
for (DormitoryScreenWebSocket item : webSocketSet) {
if (StringUtil.equals(item.screenId, screenId)) {
item.sendMessage("收到大屏" + screenId + "发来的消息:" + message);
}
}
}
/**
* 发生错误时调
*
* @OnError
**/
@OnError
public void onError(Throwable error) {
log.debug("WEBSOCKET发生错误");
error.printStackTrace();
}
public void sendMessage(String message) {
this.session.getAsyncRemote().sendText(message);
}
/**
* 发送给指定用户
*/
public void sendInfo( String message , @PathParam("screen_id") String screenId) {
for (DormitoryScreenWebSocket item : webSocketSet) {
if (StringUtil.equals(item.screenId, screenId)) {
log.info("给大屏" + screenId + "回送消息:" + message);
item.sendMessage(message);
}
}
}
/**
* 群发自定义消息
*/
public void sendInfo(String message) {
if (StringUtil.isNotEmpty(webSocketSet)) {
for (DormitoryScreenWebSocket item : webSocketSet) {
log.info("回送消息:" + message);
item.sendMessage(message);
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
DormitoryScreenWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
DormitoryScreenWebSocket.onlineCount--;
}
/**
* Map/Set的key为自定义对象时,必须重写hashCode和equals。
* 关于hashCode和equals的处理,遵循如下规则:
* 1)只要重写equals,就必须重写hashCode。
* 2)因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。
* 3)如果自定义对象做为Map的键,那么必须重写hashCode和equals。
*
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DormitoryScreenWebSocket that = (DormitoryScreenWebSocket) o;
return Objects.equals(session, that.session);
}
@Override
public int hashCode() {
return Objects.hash(session);
}
}
消息发送:
@Autowired
private DormitoryScreenWebSocket dormitoryScreenWebSocket ;
/***
*
*
* 根据管理员用户ID返回数据
*
* */
@Async
public void sendDormBaseMsg( ){
List<String> screenList = DormitoryScreenWebSocket.screenList;
if( screenList.size() != 0){
// if( userList.size() == 1 ){
String empSysId = screenList.get(0) ;
try {
log.info("sendDormBaseMsg推送实时消息!" );
JSONObject as = new JSONObject();
JSONArray ls = new JSONArray();
ls.add("dorm_data_statistics") ;
ls.add("baseDorm") ;
as.put("data" , ls ) ;
sendMsg( as.toJSONString() , empSysId ) ;
}catch( Exception ex){
log.error("WS推送发送消息异常!" + ex.getMessage() );
}
// }else{
// log.error("目前不支持多人同连1" );
//需要对当前连接的人判断,确认是否为相同的人员分组,同一组时数据群发,不同组时分开发送
// }
}else{
log.error("数据发生变化,请检查当前WebSocket连接情况!");
}
}
mian 方法入口增加配置:
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
访问地址:
ws://localhost:9092/zxks/school_dorm_websocket/123425
创建完毕后启动服务测试socket地址:(可以直接网络搜索在线测试)
http://www.websocket-test.com/
参考链接: