webSocket入门使用

websocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议.
允许服务器端主动向客户端发送数据

引入pom依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

websocket的配置文件

WebSocket服务器处理器

package com.medical.medical.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * WebSocket服务器处理器
 */
@Component
public class MyWebSocketHandler implements WebSocketHandler {
    private static Map<String, WebSocketSession> userIdMap = new HashMap<String, WebSocketSession>();//map中存储当前登录用户的ID,和客户端WebSocketSession
    @Autowired
    private ObjectMapper jackson;
    /**
     * @OnOpen
     * 连接建立后处理
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession)throws Exception {
       // System.out.println("@OnOpen webSocketSession中的 userName=>"+webSocketSession.getAttributes().get("userName"));//取出weSocketSession中的当前用户名称
       // System.out.println("@OnOpen webSocketSession中的 uId=>"+webSocketSession.getAttributes().get("uId"));//取出weSocketSession中的当前用户Id
        String uId = (String) webSocketSession.getAttributes().get("uId");
        if (uId != null) {
            userIdMap.put(uId, webSocketSession);//客户端连接服务器时,把当前用户Id和当前用户weSocketSession存储起来备用,以后用weSocketSession给客户端发消息
        }
//测试发送一句回复的话
        //sendMessageToUser(uId, uId+"你好我是服务器发送来的数据你接收到显示在控制台了吧");
    }
    /**
     * @OnMessage
     *
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> message)
            throws Exception {
        System.err.println("@OnMessage服务器接收到客户端的数据 =>"+message.getPayload().toString());
        if(message.getPayloadLength()==0)return;
//Message msg=jackson.readValue(message.getPayload().toString(),Message.class);
//Message msg=newObjectMapper().readValue(message.getPayload().toString(),Message.class);
//sendMessageToUser(msg.getTo(), new TextMessage(newObjectMapper().writeValueAsString(msg)));
        String toUserId = (String) webSocketSession.getAttributes().get("uId");//取出自己的uId
        String toUserMessage = "你好你自己发的你自己收到我的数据了吗";
        sendMessageToUser(toUserId, toUserMessage);//给指定userId的用户发送信息
        String broadMessage = "大家好,我是新来的,请多多关照!!!";
        broadcast(broadMessage);//给当前服务器所有客户端发送信息
    }
    /**
     * @OnError
     * 抛出异常时处理
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession,Throwable exception)
            throws Exception {
        String uId = (String) webSocketSession.getAttributes().get("uId");
        System.err.println("@OnError服务器与"+uId+"客户 端"+webSocketSession.getAttributes().get("userName")+"通信异常错误=>"+exception);
    }
    /**
     * @OnClose
     * 客户端关闭连接后
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        String uId = (String) webSocketSession.getAttributes().get("uId");
        System.out.println("@OnClose客户端浏览器关闭"+uId+"客户端"+webSocketSession.getAttributes().get("userName"));
// 移除WebSocket会话
                userIdMap.remove(uId);//移除已经关闭的客户端
    }

    /**
     * WebSocketHandler是否处理部分消息。
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;//WebSocket接收信息不拆分.
    }


    /**
     * 给所有在线用户发送消息
     * 多线程发送
     * @param message
     * @throws IOException
     */
    public void broadcast(final String message) throws IOException {
        final TextMessage textMessage = new TextMessage(message);
        Iterator<Map.Entry<String, WebSocketSession>> it = userIdMap.entrySet().iterator();
// 多线程群发
        while (it.hasNext()) {
            final Map.Entry<String, WebSocketSession> entry = it.next();
            if (entry.getValue().isOpen()) {
// entry.getValue().sendMessage(message);
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            if (entry.getValue().isOpen()) {
                                entry.getValue().sendMessage(textMessage);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    }
    /**
     * 给某个用户发送消息
     * @param uid
     * @param message
     * @throws IOException
     */
    public void sendMessageToUser(String uid, String message)throws IOException {
        WebSocketSession session = userIdMap.get(uid);
        if (session != null && session.isOpen()){ ;
            session.sendMessage(new TextMessage(message));
        }
    }

}

启动websocket服务器

package com.medical.medical.util;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import javax.annotation.Resource;

@Component //扫描到Spring IOC容器
@EnableWebSocket //启用WebSocket服务器
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
    @Resource
    MyWebSocketHandler myWebSocketHandler;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//WebSocket通道
        registry.addHandler((WebSocketHandler) myWebSocketHandler, "/myWebsocket").addInterceptors(new
                MyHandShakeInterceptor());
        registry.addHandler((WebSocketHandler) myWebSocketHandler, "/myWebsocket/sockjs").addInterceptors(new
                MyHandShakeInterceptor()).withSockJS();
//-------------------- 允许跨域访问WebSocket ------------------------
        String[] allowsOrigins = {"*"};//允许连接的域,只能以http或https开头

    }
}

websocket拦截器

package com.medical.medical.util;


import com.sun.javafx.collections.MappingChange;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * 拦截器实现
 * Socket建立连接(握手)和断开
 */
public class MyHandShakeInterceptor implements HandshakeInterceptor {
    /**
     * 在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置
     WebSocketSession的属性
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
//取出javax.servlet.http.HttpSession中的 uId 属性值
        System.out.println("在握手之前执行该方法.Websocket:用户连接成功 [HttpSession中属性 uId:" + ((ServletServerHttpRequest) request).getServletRequest().getSession(false).getAttribute("uId") + "]已经建立连接");
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletRequest.getServletRequest().getSession(false);
            String sessionId = session.getId();
            System.out.println("HandshakeInterceptor 开始处理一次WebSocket服务+sessionId=>"+sessionId);
            System.out.println("HttpSession中的userName=>"+session.getAttribute("userName"));
            System.out.println("HttpSession中的uId=>"+session.getAttribute("uId"));
            System.out.println("HandshakeInterceptor WebSocketSession中的uId设置值之前 =>"+attributes.get("uId"));
// 标记用户
            String uId = (String) session.getAttribute("uId");
            if( uId != null ){
                attributes.put("uId", uId);//向WebSocketSession中放入uId属性值
                attributes.put("userName", session.getAttribute("userName"));
            }else{
//return false;//禁止访问WebSocket服务
                return true;//放行 WebSocket服务
            }
        }
        return true;
    }
    /**
     * 在握手之后执行该方法. 无论是否握手成功都指明了响应状态码和相应头.
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Exception exception) {
        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
        HttpSession session = servletRequest.getServletRequest().getSession(false);
        String sessionId = session.getId();
        System.out.println("在握手之后执行该方法.处理完一次WebSocket服务 sessionId=>"+sessionId);
    }
}

##controller
–注入socket

 @Autowired
    MyWebSocketHandler myWebSocketHandler;

  myWebSocketHandler.broadcast(json.toJSONString()); // 给所有用户发送消息

//发送消息  拦截器中webSocketsession中存入的uId     json  要发送的消息
  myWebSocketHandler.sendMessageToUser(uId,json.toJSONString());  //调用方法给用户发送新消息

##前台

–将代码放在js文件中 ,使用js函数将声明的webSocket客户端返回 在需要的页面接收


定义function getWebSocket()

var wsurl = "ws://localhost:8080/myWebsocket"; //WebSocket服务器地址

var regissocket;//声明一个WebSocket客户端
//检测浏览器兼容性
if ('WebSocket' in window) {
    regissocket = new WebSocket(wsurl);//当前所有浏览器全部都支持
    console.log("当前所有浏览器全部都支持 WebSocket in window =>"+regissocket);
} else if ('MozWebSocket' in window) {
    regissocket = new MozWebSocket(wsurl);//基本没用
    console.log("基本没用 MozWebSocket in window =>"+regissocket);
} else {
    regissocket = new SockJS(sockurl);//基本没用
    console.log("基本没用 else new SockJS=>"+regissocket);
}
   
 
 //方法
//********* 成功连接服务器 *********
regissocket.onopen = function(event) {
    console.log("WebSocket:成功连接服务器 ");

};

//一般放在界面使用
regissocket.onmessage = function(event) {
    console.log("wesocket接收服务器数据event=>"+event);
    console.log("wesocket接收服务器数据event.data=>"+event.data);
    var mage=JSON.parse(event.data);//event.data是JSON格式字符串,转为JS对象
    console.log("wesocket接收服务器data=>"+mage.data.id);
    }

//********* 服务器发生异常错误 *********
regissocket.onerror = function(event) {
    console.log("WebSocket:服务器发生异常错误 ");
    console.log(event);
};
//********* 服务器关闭 *********
regissocket.onclose = function(event) {
    console.log("WebSocket:已关闭");
    console.log(event);
};
返回 regissocket

页面引入js文件

页面 打开webSocket 调用onmessage方法接收 (页面中接收请将js中的onmessage注释)
var socket = getWebSocket();
socket.onmessage=function(even){}接收信息  同上
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!要入门前端的 WebSocket,你需要了解以下几个方面: 1. WebSocket 是什么? WebSocket 是一种在客户端和服务器之间进行实时双向通信的协议。它与传统的 HTTP 请求不同,能够实现服务器向客户端推送数据,而不需要客户端发送请求。 2. 如何使用 WebSocket? 在前端,你可以使用 JavaScript 中提供的 WebSocket API 来建立 WebSocket 连接。通过创建一个 WebSocket 对象,指定连接的 URL,你可以连接到服务器并进行通信。 3. 建立 WebSocket 连接: 使用 JavaScript 的 `new WebSocket(url)` 方法可以创建一个 WebSocket 对象。`url` 参数是指定服务器的地址。例如,`ws://example.com/socket`。 4. WebSocket API: WebSocket 对象提供了一些常用的方法和事件,用于控制连接和处理数据。常见的方法包括:`send()` 用于向服务器发送数据,`close()` 用于关闭连接。常见的事件包括:`onopen` 连接建立时触发,`onmessage` 接收到消息时触发,`onclose` 连接关闭时触发等。 5. 服务器端处理: WebSocket 是一种双向通信协议,它需要在服务器端进行相应的处理。服务器端可以使用不同的编程语言来实现 WebSocket 的功能,如 Node.js 的 `ws` 模块或其他编程语言的相应库。 如果你是前端 WebSocket 的初学者,我建议你先了解 WebSocket 的基本概念和使用方法,然后通过实践来深入学习并体验其功能。你可以找一些示例代码来尝试建立连接、发送消息和接收消息等操作。希望对你有所帮助!如果你有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值