精华内容
下载资源
问答
  • 前端开源库-robust-websocket健壮的websocket,浏览器的健壮的重新连接websocket客户机
  • 前端开源库-angular2-websocketAngular2 WebSocket,基于https://github.com/angularclass/angular-websocket并迁移到Angular2安装
  • 前端开源库-home-assistant-js-websocket家庭助理JS WebSocket,家庭助理WebSocket客户端
  • 代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8">...WebSocket测试</title> </head> <body> <p>WebSocket</p> &l...
    	代码如下
    
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>WebSocket测试</title>
    </head>
    
    <body>
    
        <p>WebSocket</p>
        <button type="button" onclick="testWebSocket()">测试</button>
        <script>
            const state = ['连接尚未建立', '连接已建立,可以进行通信', '连接正在进行关闭', '连接已经关闭或者连接不能打开'];
    
            function testWebSocket() {
                var ws = new WebSocket('ws://echo.websocket.org/echo');
                console.log('ws连接状态:' + ws.readyState + ' --- ' + state[ws.readyState]);
                //监听是否连接成功
                ws.onopen = function () {
                    console.log('ws连接状态:' + ws.readyState + ' --- ' + state[ws.readyState]);
                    //连接成功则发送一个数据
                    ws.send('这是一个测试数据');
                    console.log('已发送一个数据')
                }
                //接听服务器发回的信息并处理展示
                ws.onmessage = function (data) {
                    console.log('接收到来自服务器的消息:');
                    console.log(data);
                    //完成通信后关闭WebSocket连接
                    ws.close();
                    console.log('正在关闭...');
                }
                //监听连接关闭事件
                ws.onclose = function () {
                    //监听整个过程中websocket的状态
                    console.log('ws连接状态:' + ws.readyState + ' --- ' + state[ws.readyState]);
                }
                //监听并处理error事件
                ws.onerror = function (error) {
                    console.log(error);
                }
                console.log("全部代码已执行完毕,WebSocket处于异步监听状态");
            }
        </script>
    
    </body>
    
    </html>
    
    	大家可以直接复制这个代码进行测试,理解前端webSocket的运行过程和机制。
    	(前提你的web浏览器支持WebSocket,否则还要做判断)
    

    测试的结果

    展开全文
  • WebSocket 是 HTML5 的一个引入注目的特性,它通常用于 Web 端,为构建实时的 Web 应用提供方便。WebSocket 是一个基于 TCP 的协议,它借助于 HTTP 请求,建立客户端与服务器端之间的双向...WebSocket 不是 JavaScr...

    WebSocket 是 HTML5 的一个引入注目的特性,它通常用于 Web 端,为构建实时的 Web 应用提供方便。WebSocket 是一个基于 TCP 的协议,它借助于 HTTP 请求,建立客户端与服务器端之间的双向通道,通道建立完成后,客户端和服务器端都可以通过这条通道方便地收发消息,因而 WebSocket 一向有着 “Web 的 TCP” 之称。

    WebSocket 不是 JavaScript 的一个接口,而是一个定义良好的基于消息的协议。得益于不同平台对于 WebSocket 协议的广泛实现,它更为跨多种平台的 实时网络应用程序 开发提供了极大的方便。除了可以在前端开发的 JavaScript 中使用 WebSocket 之外,我们也可以在 Java、C++、Go、Rust 等编程语言平台中使用 WebSocket。

    uWebSockets 是一个 C/C++ 的 WebSocket 库,它的GitHub 主页列出了一些常见的 WebSocket 实现库的对比.

    其中,ws-rs,项目主页,GitHub 主页,是一个轻量级的,事件驱动的用于 Rust 的 WebSocket 库。Gorilla,项目主页,GitHub 主页,是 Go 语言的 Web 工具包,它包含了 WebSocket 的实现,WebSocket 实现的GitHub 主页。websockets,项目主页,GitHub 主页,是一个 Python 的 WebSocket 实现。Socket.IO,项目主页,GitHub 主页,主要是 Node.JS 服务器的实时应用框架,其中包含了 WebSocket 的实现。其它库则都是 C/C++ 的 WebSocket 实现。

    从中我们可以捞到 uWebSockets、Crow、websocketpp、Beast 这样几个 C/C++ 的 WebSocket 库。此外,还有 libwebsockets 和 POCO 库的 WebSocket 模块。这样就总共有 6 个 C/C++ 的 WebSocket 库可以用。这里汇总已知的可以在 C++ 中使用的 WebSocket 库。

    uWebSockets

    uWebSockets,µWS ("microWS") 是一个客户端和服务器的 WebSocket 和 HTTP 实现。它简单、高效且轻量级。

    这个库在底层依赖于libuv库,作为异步网络 I/O 库。

    libwebsockets

    规范 libwebsockets.org websocket 库

    在 Mac OS 上编译通过如下方式编译这个库:

    $ git clone https://github.com/warmcat/libwebsockets.git

    $ cd libwebsockets

    $ mkdir build

    $ cd build

    $ cmake ..

    $ make

    一些比较老版本的 Mac OS 在上面执行 cmake .. 会报出如下的错误:

    -- Performing Test LWS_HAVE_VISIBILITY - Success

    Compiling with SSL support

    CMake Error at /usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:148 (message):

    Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the

    system variable OPENSSL_ROOT_DIR (missing: OPENSSL_INCLUDE_DIR)

    Call Stack (most recent call first):

    /usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)

    /usr/local/Cellar/cmake/3.5.2/share/cmake/Modules/FindOpenSSL.cmake:370 (find_package_handle_standard_args)

    CMakeLists.txt:1438 (find_package)

    -- Configuring incomplete, errors occurred!

    See also "/Users/netease/Projects/CppWebsockets/libwebsockets/build/CMakeFiles/CMakeOutput.log".

    See also "/Users/netease/Projects/CppWebsockets/libwebsockets/build/CMakeFiles/CMakeError.log".

    这主要是系统默认的 OpenSSL 库版本过老导致的。这个问题可以通过安装一个新版本的 OpenSSL 库,并在执行 cmake .. 之前定义系统环境变量 OPENSSL_ROOT_DIR 来解决,如 OpenSSL 安装在 /usr/local/opt/openssl/ 目录中,则像下面这样定义环境变量:

    $ export OPENSSL_ROOT_DIR=/usr/local/opt/openssl/

    在执行 make 编译这个库时,会报出另一个问题:

    [ 46%] Built target websockets

    Scanning dependencies of target test-server-extpoll

    [ 47%] Building C object CMakeFiles/test-server-extpoll.dir/test-apps/test-server.c.o

    [ 48%] Linking C executable bin/libwebsockets-test-server-extpoll

    clang: error: argument unused during compilation: '-pthread'

    make[2]: *** [bin/libwebsockets-test-server-extpoll] Error 1

    make[1]: *** [CMakeFiles/test-server-extpoll.dir/all] Error 2

    这个问题需要修改工程的编译配置文件,具体而言,是修改工程根目录下的 CMakeLists.txt,移除其中出现的所有 -pthread 标记。

    Poco Websocket

    POCO C++ 库是一个跨平台的 C++ 网络库。其中包含了 WebSocket 的实现模块。Poco 库是一个比较强大,比较复杂的网络库。

    在 Mac OS 上,可以通过执行 build_cmake.sh 来构建,如:

    $ ./configure  --minimal

    $ ./build_cmake.sh

    Crow

    Crow 是一个 Web 微框架。

    这个库在底层依赖于 boost 库,作为异步网络 I/O 库。

    websocketpp(WebSocket++)

    websocketpp 是 C++ 的 WebSocket 客户端/服务器库。它是一个开源的只包含头文件的 C++ 库,它实现了 RFC6455 WebSocket 协议。它允许向 C++ 程序中集成 WebSocket 客户端和服务器功能。它使用可交换的网络传输模块,包括基于 C++ iostreams 的和基于Boost Asio的。

    Beast

    基于 Boost.Asio 以 C++11 构建的 HTTP 和 WebSocket 库。Boost 项目的 HTTP 和 WebSocket 库。

    在以上的 6 个 C/C++ WebSocket 库中,其中有 3 个(Crow、websocketpp(WebSocket++)和 Beast)是基于 Boost 的网络库实现的。

    参考资料:

    展开全文
  • WebSocket 不是 JavaScript 的一个接口,而是一个定义...除了可以在前端开发的 JavaScript 中使用 WebSocket 之外,我们也可以在 Java、C++、Go、Rust 等编程语言平台中使用 WebSocket。我们汇总整理了8款目前常用的...

    WebSocket 不是 JavaScript 的一个接口,而是一个定义良好的基于消息的协议。得益于不同平台对WebSocket 协议的广泛实现,它更为跨多种平台的 实时网络应用程序开发提供了极大的方便。除了可以在前端开发的 JavaScript 中使用 WebSocket 之外,我们也可以在 Java、C++、Go、Rust 等编程语言平台中使用 WebSocket。

    我们汇总整理了8款目前常用的websocket开源框架,都是高性能的websocket库,大家可以来了解一下。

    1、GoEasy

    目前GoEasy提供完整的websocket前后端解决方案,简单的几行代码集成,即可快速搭建您专属的websocket服务。

    同时GoEasy还支持更多的前端技术框架比如小程序、react、vue、uniapp等,还支持php、java、python等服务端语言。 有websocket使用需求的开发者可以来注册GoEasy账号进行测试使用。【立即注册】

    2、 noPoll

    noPoll 是一个 WebSocket 的开源实现,使用 ANSI C 编写,可用于构建纯 WebSocket 解决方案和为已有的面向 TCP 的应用程序提供 。

    3、 Wslay

    Wslay 是一个用 C 语言实现的 WebSocket 开发库。实现了 RFC 6455 中描述的第 13 版本的协议。提供了基于事件的 API 和基于帧的底层 API。特别适合非堵塞的 reactor 模式风格应用。可在不同的事件中设置回调。Wslay 只支持 WebSocket 协议的数据传输部分,不执行 HTTP 的握手过程。

    4、 libwebsockets

    libwebsockets是lighstweight纯C库建成使用最小的CPU和内存资源,并提供快速吞吐量的两个方向。

    它支持SSL。

    5、 websocket++

    WebSocket++ 是一个只包含 C++ 头文件的 WebSocket 的 C++ 开发包,实现了 RFC 6455 也就是 WebSocket 协议。可以在 C++ 应用中实现 WebSocket 客户端和服务器端功能。使用可交换的网络传输模块,包括 C++ iostreams 和 Boost Asio。

    6、uWebSockets

    uWebSockets,µWS (“microWS”) 是一个客户端和服务器的 WebSocket 和 HTTP 实现。它简单、高效且轻量级。

    这个库在底层依赖于 libuv 库,作为异步网络 I/O 库。

    7、Poco Websocket

    POCO C++ 库是一个跨平台的 C++ 网络库。其中包含了 WebSocket 的实现模块。Poco 库是一个比较强大,比较复杂的网络库。

    8、Beast

    基于 Boost.Asio 以 C++11 构建的 HTTP 和 WebSocket 库。Boost 项目的 HTTP 和 WebSocket 库。

    在以上的 6 个 C/C++ WebSocket 库中,其中有 3 个(Crow、websocketpp(WebSocket++)和 Beast)是基于 Boost 的网络库实现的。

    展开全文
  • 前端开源库-bsock

    2019-08-29 16:58:42
    前端开源库-bsockBsock、Websocket自行车棚
  • 前端开源库-server-kit

    2019-08-29 17:35:00
    前端开源库-server-kit服务器套件,极简的HTTP和WebSocket服务器和路由器。
  • SpringBoot2.0集成WebSocket,实现后台向前端推送信息

    万次阅读 多人点赞 2018-05-10 22:54:29
    什么是WebSocket? - 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处? - 答案很简单,因为 HTTP 协议有一个缺陷:***通信只能由客户端发起***,...

    什么是WebSocket?

    这里写图片描述
    WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

    为什么需要 WebSocket?

    初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

    • 答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起,HTTP 协议做不到服务器主动向客户端推送信息。
      这里写图片描述
      举例来说,我们想要查询当前的排队情况,只能是页面轮询向服务器发出请求,服务器返回查询结果。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此WebSocket 就是这样发明的。

    前言

    2020-10-20 教程补充:

    • 补充关于@Component@ServerEndpoint关于是否单例模式等的解答,感谢大家热心提问和研究。
    • Vue版本的websocket连接方法

    2020-01-05 教程补充:

    感谢大家的支持和留言,14W访问量是满满的动力!接下来还会有websocket+redis集群优化篇针对多ws服务器做简单优化处理,敬请期待!

    话不多说,马上进入干货时刻。

    maven依赖

    SpringBoot2.0对WebSocket的支持简直太棒了,直接就有包可以引入

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

    WebSocketConfig

    启用WebSocket的支持也是很简单,几句代码搞定

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    /**
     * 开启WebSocket支持
     * @author zhengkai.blog.csdn.net
     */
    @Configuration  
    public class WebSocketConfig {  
    	
        @Bean  
        public ServerEndpointExporter serverEndpointExporter() {  
            return new ServerEndpointExporter();  
        }  
      
    } 
    

    WebSocketServer

    这就是重点了,核心都在这里。

    1. 因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller

    2. 直接@ServerEndpoint("/imserver/{userId}")@Component启用即可,然后在里面实现@OnOpen开启连接,@onClose关闭连接,@onMessage接收消息等方法。

    3. 新建一个ConcurrentHashMap webSocketMap 用于接收当前userId的WebSocket,方便IM之间对userId进行推送消息。单机版实现到这里就可以。

    4. 集群版(多个ws节点)还需要借助mysql或者redis等进行处理,改造对应的sendMessage方法即可。

    package com.softdev.system.demo.config;
    
    import java.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import org.apache.commons.lang.StringUtils;
    import org.springframework.stereotype.Component;
    import cn.hutool.log.Log;
    import cn.hutool.log.LogFactory;
    
    
    /**
     * @author zhengkai.blog.csdn.net
     */
    @ServerEndpoint("/imserver/{userId}")
    @Component
    public class WebSocketServer {
    
        static Log log=LogFactory.get(WebSocketServer.class);
        /**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
        private static int onlineCount = 0;
        /**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
        private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
        /**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
        private Session session;
        /**接收userId*/
        private String userId="";
    
        /**
         * 连接建立成功调用的方法*/
        @OnOpen
        public void onOpen(Session session,@PathParam("userId") String userId) {
            this.session = session;
            this.userId=userId;
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                webSocketMap.put(userId,this);
                //加入set中
            }else{
                webSocketMap.put(userId,this);
                //加入set中
                addOnlineCount();
                //在线数加1
            }
    
            log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
    
            try {
                sendMessage("连接成功");
            } catch (IOException e) {
                log.error("用户:"+userId+",网络异常!!!!!!");
            }
        }
    
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose() {
            if(webSocketMap.containsKey(userId)){
                webSocketMap.remove(userId);
                //从set中删除
                subOnlineCount();
            }
            log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         *
         * @param message 客户端发送过来的消息*/
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("用户消息:"+userId+",报文:"+message);
            //可以群发消息
            //消息保存到数据库、redis
            if(StringUtils.isNotBlank(message)){
                try {
                    //解析发送的报文
                    JSONObject jsonObject = JSON.parseObject(message);
                    //追加发送人(防止串改)
                    jsonObject.put("fromUserId",this.userId);
                    String toUserId=jsonObject.getString("toUserId");
                    //传送给对应toUserId用户的websocket
                    if(StringUtils.isNotBlank(toUserId)&&webSocketMap.containsKey(toUserId)){
                        webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
                    }else{
                        log.error("请求的userId:"+toUserId+"不在该服务器上");
                        //否则不在这个服务器上,发送到mysql或者redis
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    
        /**
         *
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
            error.printStackTrace();
        }
        /**
         * 实现服务器主动推送
         */
        public void sendMessage(String message) throws IOException {
            this.session.getBasicRemote().sendText(message);
        }
    
    
        /**
         * 发送自定义消息
         * */
        public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
            log.info("发送消息到:"+userId+",报文:"+message);
            if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
                webSocketMap.get(userId).sendMessage(message);
            }else{
                log.error("用户"+userId+",不在线!");
            }
        }
    
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        public static synchronized void addOnlineCount() {
            WebSocketServer.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            WebSocketServer.onlineCount--;
        }
    }
    

    消息推送

    至于推送新信息,可以再自己的Controller写个方法调用WebSocketServer.sendInfo();即可

    
    import com.softdev.system.demo.config.WebSocketServer;
    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;
    
    /**
     * WebSocketController
     * @author zhengkai.blog.csdn.net
     */
    @RestController
    public class DemoController {
    
        @GetMapping("index")
        public ResponseEntity<String> index(){
            return ResponseEntity.ok("请求成功");
        }
    
        @GetMapping("page")
        public ModelAndView page(){
            return new ModelAndView("websocket");
        }
    
        @RequestMapping("/push/{toUserId}")
        public ResponseEntity<String> pushToWeb(String message, @PathVariable String toUserId) throws IOException {
            WebSocketServer.sendInfo(message,toUserId);
            return ResponseEntity.ok("MSG SEND SUCCESS");
        }
    }
    
    

    页面发起

    页面用js代码调用websocket,当然,太古老的浏览器是不行的,一般新的浏览器或者谷歌浏览器是没问题的。还有一点,记得协议是ws的,如果使用了一些路径类,可以replace(“http”,“ws”)来替换协议。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>websocket通讯</title>
    </head>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script>
        var socket;
        function openSocket() {
            if(typeof(WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            }else{
                console.log("您的浏览器支持WebSocket");
                //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
                //等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");
                //var socketUrl="${request.contextPath}/im/"+$("#userId").val();
                var socketUrl="http://localhost:9999/demo/imserver/"+$("#userId").val();
                socketUrl=socketUrl.replace("https","ws").replace("http","ws");
                console.log(socketUrl);
                if(socket!=null){
                    socket.close();
                    socket=null;
                }
                socket = new WebSocket(socketUrl);
                //打开事件
                socket.onopen = function() {
                    console.log("websocket已打开");
                    //socket.send("这是来自客户端的消息" + location.href + new Date());
                };
                //获得消息事件
                socket.onmessage = function(msg) {
                    console.log(msg.data);
                    //发现消息进入    开始处理前端触发逻辑
                };
                //关闭事件
                socket.onclose = function() {
                    console.log("websocket已关闭");
                };
                //发生了错误事件
                socket.onerror = function() {
                    console.log("websocket发生了错误");
                }
            }
        }
        function sendMessage() {
            if(typeof(WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            }else {
                console.log("您的浏览器支持WebSocket");
                console.log('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
                socket.send('{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}');
            }
        }
    </script>
    <body>
    <p>【userId】:<div><input id="userId" name="userId" type="text" value="10"></div>
    <p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
    <p>【toUserId】:<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
    <p>【操作】:<div><a onclick="openSocket()">开启socket</a></div>
    <p>【操作】:<div><a onclick="sendMessage()">发送消息</a></div>
    </body>
    
    </html>
    

    运行效果

    • v20200105,加入开源项目spring-cloud-study-websocket,更新运行效果,更方便理解。
    • v1.1的效果,刚刚修复了日志,并且支持指定监听某个端口,代码已经全部更新,现在是这样的效果
    1. 打开两个页面,按F12调出控控制台查看测试效果:
    页面 参数
    http://localhost:9999/demo/page fromUserId=10,toUserId=20
    http://localhost:9999/demo/page fromUserId=20,toUserId=10

    分别开启socket,再发送消息
    在这里插入图片描述
    在这里插入图片描述
    2. 向前端推送数据:

    • http://localhost:9999/demo/push/10?message=123123

    在这里插入图片描述
    通过调用push api,可以向指定的userId推送信息,当然报文这里乱写,建议规定好格式。

    后续

    针对简单IM的业务场景,进行了一些优化,可以看后续的文章SpringBoot2+WebSocket之聊天应用实战(优化版本)(v20201005已整合)

    主要变动是CopyOnWriteArraySet改为ConcurrentHashMap,保证多线程安全同时方便利用map.get(userId)进行推送到指定端口。

    相比之前的Set,Set遍历是费事且麻烦的事情,而Map的get是简单便捷的,当WebSocket数量大的时候,这个小小的消耗就会聚少成多,影响体验,所以需要优化。在IM的场景下,指定userId进行推送消息更加方便。

    Websocker注入Bean问题

    关于这个问题,可以看最新发表的这篇文章,在参考和研究了网上一些攻略后,项目已经通过该方法注入成功,大家可以参考。
    关于controller调用controller/service调用service/util调用service/websocket中autowired的解决方法

    netty-websocket-spring-boot-starter

    Springboot2构建基于Netty的高性能Websocket服务器(netty-websocket-spring-boot-starter)
    只需要换个starter即可实现高性能websocket,赶紧使用吧

    Springboot2+Netty+Websocket

    Springboot2+Netty实现Websocket,使用官方的netty-all的包,比原生的websocket更加稳定更加高性能,同等配置情况下可以handle更多的连接。

    代码样式全部已经更正,也支持websocket连接url带参数功能,另外也感谢大家的阅读和评论,一起进步,谢谢!~~

    ServerEndpointExporter错误

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘serverEndpointExporter’ defined in class path resource [com/xxx/WebSocketConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available

    感谢@来了老弟儿 的反馈:

    如果tomcat部署一直报这个错,请移除 WebSocketConfig@Bean ServerEndpointExporter 的注入 。

    ServerEndpointExporter 是由Spring官方提供的标准实现,用于扫描ServerEndpointConfig配置类和@ServerEndpoint注解实例。使用规则也很简单:

    1. 如果使用默认的嵌入式容器 比如Tomcat 则必须手工在上下文提供ServerEndpointExporter
    2. 如果使用外部容器部署war包,则不需要提供提供ServerEndpointExporter,因为此时SpringBoot默认将扫描服务端的行为交给外部容器处理,所以线上部署的时候要把WebSocketConfig中这段注入bean的代码注掉。

    正式项目的前端WebSocket框架 GoEasy

    感谢kkatrina的补充,正式的项目中,一般是用第三方websocket框架来做,稳定性、实时性有保证的多,也会包括一些心跳、重连机制。

    GoEasy专注于服务器与浏览器,浏览器与浏览器之间消息推送,完美兼容世界上的绝大多数浏览器,包括IE6, IE7之类的非常古老的浏览器。支持Uniapp,各种小程序,react,vue等所有主流Web前端技术。
    GoEasy采用 发布/订阅 的消息模式,帮助您非常轻松的实现一对一,一对多的通信。
    https://www.goeasy.io/cn/doc/

    @Component@ServerEndpoint关于是否单例模式,能否使用static Map等一些问题的解答

    看到大家都在热心的讨论关于是否单例模式这个问题,请大家相信自己的直接,如果websocket是单例模式,还怎么服务这么多session呢。

    1. websocket是原型模式@ServerEndpoint每次建立双向通信的时候都会创建一个实例,区别于spring的单例模式。
    2. Spring的@Component默认是单例模式,请注意,默认 而已,是可以被改变的。
    3. 这里的@Component仅仅为了支持@Autowired依赖注入使用,如果不加则不能注入任何东西,为了方便。
    4. 什么是prototype 原型模式? 基本就是你需要从A的实例得到一份与A内容相同,但是又互不干扰的实例B的话,就需要使用原型模式。
    5. 关于在原型模式下使用static 的webSocketMap,请注意这是ConcurrentHashMap ,也就是线程安全/线程同步的,而且已经是静态变量作为全局调用,这种情况下是ok的,或者大家如果有顾虑或者更好的想法的化,可以进行改进。 例如使用一个中间类来接收和存放session。
    6. 为什么每次都@OnOpen都要检查webSocketMap.containsKey(userId) ,首先了为了代码强壮性考虑,假设代码以及机制没有问题,那么肯定这个逻辑是废的对吧。但是实际使用的时候发现偶尔会出现重连失败或者其他原因导致之前的session还存在,这里就做了一个清除旧session,迎接新session的功能。

    Vue版本的websocket连接

    感谢**@GzrStudy**的贡献,供大家参考。

    <script>
    export default {
        data() {
            return {
                socket:null,
                userId:localStorage.getItem("ms_uuid"),
                toUserId:'2',
                content:'3'
            }
        },
      methods: {
        openSocket() {
          if (typeof WebSocket == "undefined") {
            console.log("您的浏览器不支持WebSocket");
          } else {
            console.log("您的浏览器支持WebSocket");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            //等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");
            //var socketUrl="${request.contextPath}/im/"+$("#userId").val();
            var socketUrl =
              "http://localhost:8081/imserver/" + this.userId;
            socketUrl = socketUrl.replace("https", "ws").replace("http", "ws");
            console.log(socketUrl);
            if (this.socket != null) {
              this.socket.close();
              this.socket = null;
            }
            this.socket = new WebSocket(socketUrl);
            //打开事件
            this.socket = new WebSocket(socketUrl);
            //打开事件
            this.socket.onopen = function() {
              console.log("websocket已打开");
              //socket.send("这是来自客户端的消息" + location.href + new Date());
            };
            //获得消息事件
            this.socket.onmessage = function(msg) {
              console.log(msg.data);
              //发现消息进入    开始处理前端触发逻辑
            };
            //关闭事件
            this.socket.onclose = function() {
              console.log("websocket已关闭");
            };
            //发生了错误事件
            this.socket.onerror = function() {
              console.log("websocket发生了错误");
            };
          }
        },
        sendMessage() {
          if (typeof WebSocket == "undefined") {
            console.log("您的浏览器不支持WebSocket");
          } else {
            console.log("您的浏览器支持WebSocket");
            console.log(
              '{"toUserId":"' +
                 this.toUserId +
                '","contentText":"' +
                 this.content +
                '"}'
            );
            this.socket.send(
              '{"toUserId":"' +
                 this.toUserId +
                '","contentText":"' +
                 this.content +
                '"}'
             );
        
        }
    }
    
    展开全文
  • 前端开源项目周报0328

    2017-03-28 16:35:09
    由OpenDigg 出品的前端开源项目周报第十四期来啦。我们的前端开源周报集合了OpenDigg一周来新收录的优质的前端开源项目,方便前端开发人员便捷的找到自己需要的项目工具等。 react-overdrive 超级简单的神奇移动...
  • 由OpenDigg 出品的前端开源项目月报第一期来啦。我们的前端开源月报集合了OpenDigg一个月来新收录的优质前端开源项目,方便前端开发人员便捷的找到自己需要的项目工具。reactide React web应用开发的第一个专用...
  • 由OpenDigg出品的前端开源项目月报第一期来啦。我们的前端开源月报集合了OpenDigg一个月来新收录的优质前端开源项目,方便前端开发人员便捷的找到自己需要的项目工具。reactide React web应用开发的第一个专用...
  • WebSocket 入门及开源

    万次阅读 2019-03-07 16:45:00
    WebSocket 协议和知识 WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。 WebSocket使得客户端和...
  • 2020年常用websocket开源库整理汇总

    千次阅读 2020-02-19 16:25:08
    websocket是html5中新增的协议,websocket的特点是全双工,服务端和...除了可以在前端开发的JavaScript 中使用 WebSocket 之外,我们也可以在 Java、C++、Go、Rust 等编程语言平台中使用 WebSocket。 我汇总整理了8...
  • 前端websocket开发

    2019-08-19 11:46:02
    时至今日,websocket前端开发中占据着很重要的地位,如极其常用的心跳检测功能。甚至还有大量的站点以其作为主要的数据传输工具以替代Ajax,以下我们来介绍下如何正常地使用websocket进行前端开发。
  • 前端开源自定义报表luckysheet.js

    千次阅读 2020-10-26 15:05:56
    前端开源自定义报表luckysheet.js demo实例 代码片 此处增加保存、加载、导入、导出JS 功能配置参考 https://mengshukeji.github.io/LuckysheetDocs/guide/ <!DOCTYPE html> <html lang="en"> <...
  • web前端开源框架 大约十年前,JavaScript开发人员社区开始目睹JavaScript框架之间出现的激烈战斗。 在本文中,我将介绍一些最著名的框架。 需要特别注意的是,这些都是开放源代码JavaScript项目,这意味着您可以在...
  • websocketd是WebSocket守护程序。 它负责处理WebSocket连接,启动程序以处理WebSocket以及在程序和Web浏览器之间传递消息。 如果可以从命令行运行程序,则可以编写... 在构建前端之前,请与WebSocket程序进行交互。
  • 前端开源总结

    2019-12-11 20:32:37
    Vue相关开源项目库汇总 element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 UI 组件库 mint-ui ★6253 - Vue 2的移动UI元素 muse-ui ...
  • 使用websocket连接Activemq,让前端接收MQTT消息Activemq简介准备工作简单示例 Activemq简介 Apache ActiveMQ™ is the most popular open source, multi-protocol, Java-based messaging server. It supports ...
  • WebRTC是一个开源项目,旨在使得浏览器能为实时通信(RTC)提供简单的JavaScript接口。说的简单明了一点就是让浏览器提供JS的即时通信接口。这个接口所创立的信道并不是像WebSocket一样,打通一个浏览器与WebSocket...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,217
精华内容 3,286
关键字:

websocket前端开源