在手机上相信都有来自服务器的推送消息,比如一些及时的新闻信息,这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是websocket技术。
一、什么是websocke
tWebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,学过计算机网络都知道,既然是全双工,就说明了服务器可以主动发送信息给客户端。这与我们的推送技术或者是多人在线聊天的功能不谋而合。
为什么不使用HTTP 协议呢?这是因为HTTP是单工通信,通信只能由客户端发起,客户端请求一下,服务器处理一下,这就太麻烦了。于是websocket应运而生。
下面我们就直接开始使用Springboot开始整合。以下案例都在我自己的电脑上测试成功,你可以根据自己的功能进行修改即可。
二、整合websocket
1、环境配置
Idea 2018专业版(已破解)
Maven 4.0.0
SpringBoot 2.2.2
websocket 2.1.3
jdk 1.8
下面我们新建一个普通的Springboot项目。
2、添加依赖
-
-
org.springframework.boot -
spring-boot-starter-web -
-
-
org.springframework.boot -
spring-boot-starter-test -
test -
-
-
org.springframework.boot -
spring-boot-starter-websocket -
2.1.3.RELEASE -
-
3、在application.properties文件修改端口号
一句话:server.port=8081
4、新建config包,创建WebSocketConfig类
- 1@Configuration
- 2public class WebSocketConfig {
- 3 @Bean
- 4 public ServerEndpointExporter serverEndpointExporter() {
- 5 return new ServerEndpointExporter();
- 6 }
- 7}
5、新建service包,创建WebSocketServer类
- @ServerEndpoint("/websocket/{sid}")
- @Component
- public class WebSocketServer {
- static Log log= LogFactory.getLog(WebSocketServer.class);
- //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
- private static int onlineCount = 0;
- //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
- private static CopyOnWriteArraySet
webSocketSet - = new CopyOnWriteArraySet
(); - //与某个客户端的连接会话,需要通过它来给客户端发送数据
- private Session session;
- //接收sid
- private String sid="";
-
- @OnOpen
- public void onOpen(Session session,@PathParam("sid") String sid) {
- this.session = session;
- webSocketSet.add(this); //加入set中
- addOnlineCount(); //在线数加1
- log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
- this.sid=sid;
- try {
- sendMessage("连接成功");
- } catch (IOException e) {
- log.error("websocket IO异常");
- }
- }
-
- @OnClose
- public void onClose() {
- webSocketSet.remove(this); //从set中删除
- subOnlineCount(); //在线数减1
- log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
- }
-
- @OnMessage
- public void onMessage(String message, Session session) {
- log.info("收到来自窗口"+sid+"的信息:"+message);
- //群发消息
- for (WebSocketServer item : webSocketSet) {
- try {
- item.sendMessage(message);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- @OnError
- public void onError(Session session, Throwable error) {
- log.error("发生错误");
- error.printStackTrace();
- }
- //实现服务器主动推送
- public void sendMessage(String message) throws IOException {
- this.session.getBasicRemote().sendText(message);
- }
- //群发自定义消息
- public static void sendInfo(String message,@PathParam("sid") String sid)
- throws IOException {
- log.info("推送消息到窗口"+sid+",推送内容:"+message);
- for (WebSocketServer item : webSocketSet) {
- try {
- //这里可以设定只推送给这个sid的,为null则全部推送
- if(sid==null) {
- item.sendMessage(message);
- }else if(item.sid.equals(sid)){
- item.sendMessage(message);
- }
- } catch (IOException e) {
- continue;
- }
- }
- }
- public static synchronized int getOnlineCount() {
- return onlineCount;
- }
- public static synchronized void addOnlineCount() {
- WebSocketServer.onlineCount++;
- }
- public static synchronized void subOnlineCount() {
- WebSocketServer.onlineCount--;
- }
6、新建controller包,创建Mycontroller类
- @Controller
- public class MyController {
- //页面请求
- @GetMapping("/socket/{cid}")
- public ModelAndView socket(@PathVariable String cid) {
- ModelAndView mav=new ModelAndView("/socket");
- mav.addObject("cid", cid);
- return mav;
- }
- //推送数据接口
- @ResponseBody
- @RequestMapping("/socket/push/{cid}")
- public String pushToWeb(@PathVariable String cid,String message) {
- try {
- WebSocketServer.sendInfo(message,cid);
- } catch (IOException e) {
- e.printStackTrace();
- return "推送失败";
- }
- return "发送成功";
- }
- }}
7、新建一个websocket.html页面
-
-
- name="viewport" content="initial-scale=1.0, user-scalable=no" />
-
-
-
现在开发服务器和网页就可以看到效果了。一般情况下Springboot2+Netty+Websocket的组合方式更加的常用一下。这个只是给出了一个基本的案例,你可以根据自己的需求进行更改。
本文转载自微信公众号「愚公要移山」,可以通过以下二维码关注。转载本文请联系愚公要移山公众号。