简单几步,在spring-boot项目中配置和实现websocket的服务端和html客户端:
1、引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、配置文件配置
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3、服务端实现
@ServerEndpoint("/my-websocket")
@Component
public class MyWebSocket {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
private static int onlineCount = 0;
private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<>();
private Session session;
@OnOpen
public void onOpen(Session session) throws IOException{
this.session = session;
webSocketSet.add(this);
incrOnlineCount();
for(MyWebSocket item : webSocketSet){
if(!item.equals(this)) { //send to others only.
item.sendMessage("someone just joined in.");
}
}
logger.info("new connection...current online count: {}", getOnlineCount());
}
@OnClose
public void onClose() throws IOException{
webSocketSet.remove(this);
decOnlineCount();
for(MyWebSocket item : webSocketSet){
item.sendMessage("someone just closed a connection.");
}
logger.info("one connection closed...current online count: {}", getOnlineCount());
}
@OnMessage
public void onMessage(String message, Session session) throws IOException {
logger.info("message received: {}", message);
// broadcast received message
for(MyWebSocket item : webSocketSet){
item.sendMessage(message);
}
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount(){
return MyWebSocket.onlineCount;
}
public static synchronized void incrOnlineCount(){
MyWebSocket.onlineCount++;
}
public static synchronized void decOnlineCount(){
MyWebSocket.onlineCount--;
}
}
4、客户端(html+vue.js)实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My WebSocket</title>
<script src="js/vue.js"></script>
</head>
<body>
Welcome To My WebSocket.<br/><br/>
<div id="ws">
<input id="text" type="text"/>
<button οnclick="sendMsg()">Send</button>
<button οnclick="closeWS()" :disabled="!opened">Close</button>
<button οnclick="openWS()" :disabled="opened">Open</button>
<div v-html="msg"></div>
</div>
</body>
<script type="text/javascript">
var websocket = null;
var wsVue = new Vue({
el: '#ws',
data: {
msg: "welcome to my websocket...<br/>",
opened: false
},
mounted: function(){
initWs();
}
});
function initWs() {
//check if your browser supports WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8082/my-websocket");
}
else {
alert('Sorry, websocket not supported by your browser.')
}
//Error callback
websocket.onerror = function () {
setMessageContent("error!");
wsVue.opened = false;
};
//socket opened callback
websocket.onopen = function (event) {
setMessageContent("websocket opened");
wsVue.opened = true;
}
//message received callback
websocket.onmessage = function (event) {
setMessageContent(event.data);
}
//socket closed callback
websocket.onclose = function () {
setMessageContent("websocket closed");
wsVue.opened = false;
}
//when browser window closed, close the socket, to prevent server exception
window.onbeforeunload = function () {
websocket.close();
}
}
//update message to vue and then in div
function setMessageContent(content) {
wsVue.msg += content + '<br/>';
}
//click to close the websocket
function closeWS() {
websocket.close();
wsVue.opened = false;
}
//click to open the websocket
function openWS() {
initWs();
}
//click to send message
function sendMsg() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</body>
</html>
5、效果
第一个客户端:
第二个客户端:
注意:上面这种配置有个缺点,就是MyWebSocket类里面无法使用@Value或@Autowired之类的Spring注入。
所以,更简单的结合Spring的实现方法如下:
第2步,配置,改为:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(CmdHandler(), "/my-websocket"); //url和handler的mapping
}
@Bean
public WebSocketHandler CmdHandler() {
return new CmdHandler();
}
}
第3步,服务端的实现,改为:
public class CmdHandler extends TextWebSocketHandler {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${spring.profiles}")
private String env;
@Autowired
MyService myService;
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
TextMessage msg = new TextMessage("Hello, " + message.getPayload() + "!");
logger.info("message received: {}", message.getPayload());
try {
session.sendMessage(msg);
}
}catch (IOException e){
logger.error(e.getMessage(), e);
}
}
}