1、maven依赖WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
为什么需要 WebSocket?
初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息。
2、WebSocketConfigorg.springframework.boot spring-boot-starter-websocket
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }3、WebSocketServer
因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller
新建websocket的Controller
直接@ServerEndpoint("/websocket") 、@Component启用即可,然后在里面实现@OnOpen开启连接,@onClose关闭连接,@onMessage接收消息等方法。
新建一个ConcurrentHashMap servers 客户端连接信息
用于接收当前Session的WebSocket,方便IM之间对当前连接进行推送消息。
import com.alibaba.fastjson.JSON; import io.demo.common.constant.Constant; import io.demo.websocket.config.WebSocketConfig; import io.demo.websocket.data.MessageData; import io.demo.websocket.data.WebSocketData; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Component @ServerEndpoint(value = "/websocket", configurator = WebSocketConfig.class) public class WebSocketServer { private static Map4、消息推送servers = new ConcurrentHashMap<>(); @onOpen public void open(Session session) { Long userId = (Long) session.getUserProperties().get(Constant.USER_KEY); servers.put(session.getId(), new WebSocketData(userId, session)); } @onClose public void onClose(Session session) { //客户端断开连接 servers.remove(session.getId()); log.debug("websocket close, session id:" + session.getId()); } @onError public void onError(Session session, Throwable throwable) { servers.remove(session.getId()); log.error(throwable.getMessage(), throwable); } @onMessage public void onMessage(Session session, String msg) { log.info("session id: " + session.getId()+", message:" + msg); } public void sendMessage(List userIdList, MessageData> message) { userIdList.forEach(userId -> sendMessage(userId, message)); } public void sendMessage(Long userId, MessageData> message) { servers.values().forEach(info -> { if (userId.equals(info.getUserId())) { sendMessage(info.getSession(), message); } }); } public void sendMessageAll(MessageData> message) { servers.values().forEach(info -> sendMessage(info.getSession(), message)); } public void sendMessage(Session session, MessageData> message) { try { session.getBasicRemote().sendText(JSON.toJSonString(message)); } catch (IOException e) { log.error("send message error," + e.getMessage(), e); } } }
可以在自己的Controller写个方法调用WebSocketServer.sendMessage()。
import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import java.io.IOException; @RestController public class DemoController { @Autowired private WebSocketServer webSocketServer; @RequestMapping("/push/{toUserId}") public ResponseEntitypushToWeb(@PathVariable String toUserId) throws IOException { String message="WebSocket"; WebSocketServer.sendMessage(toUserId,message); return ResponseEntity.ok("MSG SEND SUCCESS"); } }
5、页面发起
test () { this.$http.get('/push/'+toUserId).then(({ data: res }) => { if (res.code !== 0) { return this.$message.error(res.msg) } }).catch(() => { }) var vue = this socket = new WebSocket(`${window.SITE_CONFIG['socketURL']}`) socket.onopen = function () { } socket.onerror = function () { vue.$notify.error({ title: vue.$t('notice.disconnect'), message: vue.$t('notice.disconnectMessage') }) } socket.onmessage = function (evt) { const result = JSON.parse(evt.data) if (result.type === 0) { vue.$notify({ title: vue.$t('notice.new'), message: result.msg, type: 'info', duration: 5000 }) } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)