java webSocket
前端代码
连接WEBSOCKET
后端代码
--引入包
import cn.com.zhengya.framework.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.stereotype.Component;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* webSocket客户端
* @author luwl
* @date 2021/1/13 10:54
* @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
* {mac}是传递唯一标识的识别参数
*/
@Slf4j
@Component
@ServerEndpoint("/socket/{mac}")
public class WebSocketServer {
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
/**
* 存活的session集合(使用线程安全的map保存)
*/
private static Map livingSessions = new ConcurrentHashMap<>();
/**
* 在线的连接对象
*/
private static volatile int livingCount = 0;
/**
* 当前的session对象
*/
private Session session;
/**
* 建立连接的回调方法
*
* @param session 与客户端的WebSocket连接会话
* @param mac 硬件MAC地址 唯一
*/
@OnOpen
public void onOpen(Session session, @PathParam("mac") String mac) {
if (!livingSessions.containsKey(mac)) {
webSocketSet.add(this);
livingSessions.put(mac, session);
this.session = session;
addLivingCount();
log.info(mac + " 进入连接,当前连接中数量为:" + getLivingCount());
} else {
log.info(mac + "重新连接,当前连接中数量为:" + getLivingCount());
}
}
@OnMessage
public void onMessage(String message, Session session, @PathParam("mac") String mac) {
log.info(mac + " : " + message);
sendMessageToAll(message);
}
@OnError
public void onError(Session session, Throwable error) {
log.info("发生错误");
log.error(error.getStackTrace() + "");
}
@OnClose
public void onClose(Session session, @PathParam("mac") String mac) {
webSocketSet.remove(this);
livingSessions.remove(mac);
subLivingCount();
log.info(mac + " 关闭连接,当前连接中数量为:" + getLivingCount());
}
/**
* 单独发送消息到指定用户
*
* @param message
*/
public void sendMessage(String mac, String message) {
try {
if (getLivingCount() != 0) {
livingSessions.get(mac).getBasicRemote().sendText(message);
} else {
throw new ServiceException("当前无连接对象");
}
} catch (IOException e) {
log.info("sendMessage error", e);
}
}
/**
* 单独发送消息到当前用户
*
* @param message
*/
public void sendMessage(String message) {
try {
synchronized (this) {
this.session.getBasicRemote().sendText(message);
}
} catch (IOException e) {
log.info("sendMessage error", e);
}
}
/**
* 群发消息
*
* @param message
*/
public void sendMessageToAll(String message) {
if (getLivingCount() != 0) {
for (WebSocketServer server : webSocketSet) {
server.sendMessage(message);
}
} else {
throw new ServiceException("当前无连接对象");
}
}
public static synchronized int getLivingCount() {
return livingCount;
}
public static synchronized void addLivingCount() {
WebSocketServer.livingCount++;
}
public static synchronized void subLivingCount() {
WebSocketServer.livingCount--;
}
/**
* 获取所有连接中对象的标识
*
* @return
*/
public List getAllMac() {
return new ArrayList<>(livingSessions.keySet());
}
}
-发送消息
@Data
@ApiModel("发送消息给指定的对象")
public class SocketParam {
@ApiModelProperty("发送对象标识(物理机器的MAC地址)")
private String mac;
@ApiModelProperty("消息")
private String message;
}
@Slf4j
@RestController
@RequestMapping("/socket/api")
@Api(value = "socket服务", tags = "socket服务")
public class SocketController {
@Autowired
private WebSocketServer webSocketServer;
@PostMapping("/sendMessageToOne")
@ApiOperation(value = "发送消息给单个通道")
public Result<?> sendMessageToOne(@RequestBody SocketParam socketParam){
webSocketServer.sendMessage(socketParam.getMac(),socketParam.getMessage());
return Result.success();
}
@PostMapping("/sendMessageToALL")
@ApiOperation(value = "发送消息给所有通道")
public Result<?> sendMessageToAll(@RequestParam String message){
webSocketServer.sendMessageToAll(message);
return Result.success();
}
@PostMapping("/getAllSession")
@ApiOperation(value = "获取所有连接中通道")
public Result<?> getAllSession(){
return Result.success(webSocketServer.getAllMac());
}
}