1、依赖
<!--websocket 服务端-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--websocket 客户端-->
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.5</version>
</dependency>
2、服务端配置
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Component
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、服务端业务处理逻辑
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@ServerEndpoint(value = "/websocket")
public class WebSocketServer {
private static ConcurrentHashMap<String, Session> clients = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
log.info("id = {}", session.getId());
log.info("uri host = {}", session.getRequestURI().getHost());
log.info("uri port = {}", session.getRequestURI().getPort());
log.info("uri = {}", session.getRequestURI().toString());
clients.put(session.getId(), session);
log.info("客户端连接id= {},当前客户端数 = {}", session.getId(), clients.size());
}
@OnClose
public void onClose(Session session) {
clients.remove(session.getId());
log.info("客户端断连id= {}, 当前客户端数 = {}", session.getId(), clients.size());
}
@OnError
public void onError(Session session, Throwable throwable) {
}
@OnMessage
public void onMessage(String message, Session session) {
log.info("接收客户端id= {}发来的消息 = {}", session.getId(), message);
}
public void sendDirectMessage(Session session, String message) {
log.info("向客户端id = {}发送消息 = {}", session.getId(), message);
session.getAsyncRemote().sendText(message);
}
public void sendFanoutMessage(String message) {
log.info("群发消息 = {}", message);
clients.values().forEach(session -> session.getAsyncRemote().sendText(message));
}
public void sendFanoutMessage(String message, Session session) {
log.info("群发消息、排除指定客户,消息内容 = {}", session);
for (Map.Entry<String, Session> entry : clients.entrySet()) {
if (session == entry.getValue()) {
continue;
}
session.getAsyncRemote().sendText(message);
}
}
public static ConcurrentHashMap getClients() {
return clients;
}
}
4、客户端配置
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.net.URI;
@Slf4j
@Component
public class WebSocketClientConfig {
private static final String WEBSOCKET_URI = "ws://localhost:8080/websocket";
@Bean(name = "client1")
public WebSocketClient webSocketClient1() {
try {
WebSocketClient webSocketClient = new WebSocketClient(new URI(WEBSOCKET_URI), new Draft_6455()) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
log.info("client1-客户端连接成功");
}
@Override
public void onMessage(String message) {
log.info("client1-客户端收到消息:{}", message);
}
@Override
public void onClose(int i, String s, boolean b) {
log.info("client1-关闭");
}
@Override
public void onError(Exception e) {
log.info("client1-错误:{}", e);
}
};
webSocketClient.connect();
return webSocketClient;
}catch (Exception e) {
log.info("创建websocket bean 异常,异常信息 = {}", e);
}
return null;
}
@Bean(name = "client2")
public WebSocketClient webSocketClient2() {
try {
WebSocketClient webSocketClient = new WebSocketClient(new URI(WEBSOCKET_URI), new Draft_6455()) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
log.info("client2-客户端连接成功");
}
@Override
public void onMessage(String message) {
log.info("client2-客户端收到消息:{}", message);
}
@Override
public void onClose(int i, String s, boolean b) {
log.info("client2-关闭");
}
@Override
public void onError(Exception e) {
log.info("client2-错误:{}", e);
}
};
webSocketClient.connect();
return webSocketClient;
}catch (Exception e) {
log.info("创建websocket bean 异常,异常信息 = {}", e);
}
return null;
}
}
5、客户端业务逻辑
import com.example.demo.websocket.server.WebSocketServer;
import org.java_websocket.client.WebSocketClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.websocket.Session;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class WebSocketClientService {
@Resource(name = "client1")
private WebSocketClient webSocketClient1;
@Resource(name = "client2")
private WebSocketClient webSocketClient2;
@Autowired
private WebSocketServer webSocketServer;
public void websocketServerSendMessage(String message) {
webSocketServer.sendFanoutMessage("群发消息" + message);
}
public void websocketServerSendSignalMessage(String message) {
ConcurrentHashMap clients = WebSocketServer.getClients();
Session session = (Session) clients.get("0");
webSocketServer.sendDirectMessage(session, "单发消息");
}
public void send1Message(String message) {
webSocketClient1.send(message);
}
public void send2Message(String message) {
webSocketClient2.send(message);
}
}
6、controller测试
import com.example.demo.websocket.client.WebSocketClientService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "websocket")
@RestController
@RequestMapping("/websocket")
public class WebSocketController {
@Autowired
private WebSocketClientService webSocketClientService;
@ApiOperation("websocket客户端1发送消息测试")
@GetMapping("/websocketClient1SendMessage")
public Object websocketClient1SendMessage(@RequestParam String message) {
webSocketClientService.send1Message(message);
return "发送成功!";
}
@ApiOperation("websocket客户端2发送消息测试")
@GetMapping("/websocketClient2SendMessage")
public Object websocketClient2SendMessage(@RequestParam String message) {
webSocketClientService.send2Message(message);
return "发送成功!";
}
@ApiOperation("服务端单发消息")
@GetMapping("/websocketServerSendSignalMessage")
public Object websocketServerSendSignalMessage(@RequestParam String message) {
webSocketClientService.websocketServerSendSignalMessage(message);
return "单发成功!";
}
@ApiOperation("服务端群发消息")
@GetMapping("/websocketServerSendMessage")
public Object websocketServerSendMessage(@RequestParam String message) {
webSocketClientService.websocketServerSendMessage(message);
return "群发成功!";
}
}
|