Java版的WebSocket

websocket实现(一):javax.websocket 阅读详情

项目背景介绍:公司新开发的APP,需要使用系统公告功能,实现实时更新系统公告功能。

 公告的修改功能,由PC端的运营管理界面来进行修改更新发布。当修改完后,要保证APP端,在用户不刷新或重新登录APP的情况下,更新公告内容。

项目的实际架构部署:

负载均衡的后面有两台服务器,部署的服务都是一样的。通过nginx来代理转发请求的具体服务。

多实例部署的情况下,会造成websocket的session不能共享。这里采用的是:redis的发布和订阅功能,实现修改后的公告消息在每台服务器上都能收到,然后再获取每台机器上的websocket会话,给APP端发送消息。 

public class Constants
{
    /** redis 订阅消息通道标识*/
    public final static String REDIS_CHANNEL = "onMessage";
    public final static String REDIS_CHANNEL_CLOSE="close";
    public final static String REDIS_CHANNEL_SEND="send";
}
 @Autowired
 private StringRedisTemplate stringRedisTemplate;

 private void sendMessage(String message) {
        String newMessge= null;
        try {
            newMessge = new String(message.getBytes(Constants.UTF8), Constants.UTF8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
//        Map<String,String> map = new HashMap<String, String>();
//        map.put(Constants.REDIS_MESSAGE_KEY, key);
//        map.put(Constants.REDIS_MESSAGE_VALUE, newMessge);
        stringRedisTemplate.convertAndSend(Constants.REDIS_CHANNEL, newMessge);//发布消息
        System.out.println("将消息: "+newMessge+ "发布出去...");
    }
package cn.com.yuanquanyun.config;

import cn.com.yuanquanyun.client.service.ws.WebSocketServer;
import cn.com.yuanquanyun.common.constant.Constants;
import cn.com.yuanquanyun.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 消息监听对象,接收订阅消息 -- 每台服务器都订阅公告消息
 */
@Component
public class RedisReceiver implements MessageListener {
    Logger log = LoggerFactory.getLogger(this.getClass());

    //@Autowired
    //private WebSocketServer webSocketServer;


    /**
     * 处理接收到的订阅消息
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        String channel = new String(message.getChannel());// 订阅的频道名称
        String msg = "";
        try {
            msg = new String(message.getBody(), Constants.UTF8);//注意与发布消息编码一致,否则会乱码
            System.out.println("打印订阅的消息:" + msg);
            if (!StringUtils.isEmpty(msg)) {
                if (Constants.REDIS_CHANNEL.endsWith(channel))// 最新消息
                {
                    //JSONObject jsonObject = JSON.parseObject(msg);

                    //将更新后的公告推送给在线的用户手机端
                    ConcurrentHashMap<String, WebSocketServer> webSocketMap = WebSocketServer.getWebSocketMap();
                    Collection<WebSocketServer> values = webSocketMap.values();
                    System.err.println("values ===" + values.size());
                    Iterator<WebSocketServer> it = values.iterator();
                    while (it.hasNext()) {
                        WebSocketServer ws = it.next();
                        try {
                            ws.sendMessage(msg);
                        } catch (IOException e) {
                            System.err.println("sendMessage_error=" + e);
                        }
                    }

//                    webSocketServer.sendMessageByWayBillId(
//                            Long.parseLong(jsonObject.get(Constants.REDIS_MESSAGE_KEY).toString())
//                            ,jsonObject.get(Constants.REDIS_MESSAGE_VALUE).toString());
                } else {
                    //TODO 其他订阅的消息处理
                }

            } else {
                log.info("消息内容为空,不处理。");
            }
        } catch (Exception e) {
            log.error("处理消息异常:" + e.toString());
            e.printStackTrace();
        }
    }
}
package cn.com.yuanquanyun.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
 * 开启websocket支持
 * @author Administrator
 */
@Configuration
//@EnableWebSocket
public class WebSocketConfig {
	
	@Bean  
    public ServerEndpointExporter serverEndpointExporter() {
        System.err.println("WebSocketConfig 初始化 ");
	    return new ServerEndpointExporter();
    }
}
<!-- springboot集成websocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
package cn.com.yuanquanyun.client.service.ws;

import cn.com.yuanquanyun.client.dto.CustNotice;
import cn.com.yuanquanyun.client.service.impl.CustNoticeServiceImpl;
import cn.com.yuanquanyun.common.utils.spring.SpringUtils;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 此方法使用于工程部署是单例的情况下,若是多例的情况下,存在userId不在一台机器上,webSocketMap中查询不到。
 * 多机的情况下,要考虑数据共享的问题,可采用redis发布和订阅来解决.
 * @author Administrator
 *
 */
@Component
@ServerEndpoint("/ws/{userId}")
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="";

    public WebSocketServer() {
		System.out.println("WebSocketServer 初始化... hashCode="+this.hashCode());
	}
    public static ConcurrentHashMap<String,WebSocketServer> getWebSocketMap(){
        return webSocketMap;
    }
    
    /**
     * 连接建立成功调用的方法 只调一次
     *
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
    	System.out.println("onOpen hashCode="+this.hashCode()+", userId="+userId);//根据打印的hashCode每建立一个连接就会生成一个新的WebSocketServer对象,与对应的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 {
//            System.out.println("custNoticeService======"+SpringUtils.getBean(CustNoticeServiceImpl.class));
            CustNotice custNotice = SpringUtils.getBean(CustNoticeServiceImpl.class).selectNotice();
//            CustNotice custNotice = custNoticeService.selectNotice();
//            System.out.println("custNotice======"+custNotice.toString());
            sendMessage(custNotice.getNoticeContent());
        } catch (IOException e) {
            log.error("用户:"+userId+",网络异常!!!!!!");
        }
    }
    
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
    	/*System.out.println("onMessage hashcode=="+this.hashCode());
        log.info("onMessage 用户消息:"+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();
            }
        }*/
    }
    
    /**
     * 页面socket连接关闭,自动调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //从set中删除
//            subOnlineCount();
        }
//        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
    }
    
    /**
    *
    * @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+",不在线!");
       }
   }*/

}
<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 = "https://localhost:9093/websocket/" + $("#userId").val();
            // var socketUrl = "wss://localhost:8096/v3/ws/" + $("#userId").val();
            // var socketUrl = "wss://yu_ming:8096/v3/ws/" + $("#userId").val();
            var socketUrl = "wss://yu_ming:8093/websk/ws/" + $("#userId").val();
            socketUrl = socketUrl.replace("https", "wss").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($("#contentText").val());
            socket.send($("#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>

通过html界面功能可以模拟和后端建立websocket长连接。使用wss时app端要通过域名来访问。

这里有个小插曲:

生产环境app端请求后台是通过nginx代理转发到服务端的。测试环境没有通过nginx转发。

这里的nginx下的nginx.conf文件里需要配置一下支持websocket协议。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
    }
    server {
        listen       8093;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;


        location /v2 {
            proxy_pass  http://10.0.0.10:8082/v2;
        }

	location /v3 {
            proxy_pass  http://10.0.0.10:8083/v3;
        }

	location /websk {
            proxy_pass http://10.0.0.10:8083/v3;
            
            proxy_read_timeout 300s;
            proxy_send_timeout 300s;
            
            proxy_set_header Host $host;
            proxy_set_header X-real-ip $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }

        location /404 {
                index index.html index.htm;
                root  /usr/share/nginx/html;
                error_page 404 /index.html;
        }
        location / {
                index index.html index.htm;
                root  /usr/share/nginx/html;
                error_page 404 /index.html;
        }
        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

里面的关键部分是:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

location /websk {
            proxy_pass http://10.0.0.10:8083/v3;
            
            proxy_read_timeout 300s;
            proxy_send_timeout 300s;
            
            proxy_set_header Host $host;
            proxy_set_header X-real-ip $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
}

JavaWeb之WebSocket 客户端向 WebSocket 服务器通知(notify)一个带有所有接收者ID(recipients IDs)的事件(event),服务器接收后立即通知所有活跃的(active)客户端,只有ID在接收者ID序列中的客户端才会处理这个事件。可以通过读取readyState的属性值来获取WebSocket对象的状态,readyState属性存在以下几种属性值。WebSocket需要接收一个url参数,然后调用WebSocket对象的构造器来建立与服务器之间的通信链接。WebSocket的状态。 阅读详情

相关推荐

WebSocket详解(Java后端,基于Springboot)

WebSocket是一种在单个TCP连接上进行全双工通信的协议。这种协议在2011年被IETF定为标准RFC 6455,并由RFC7936补充规范,同时WebSocket API也被W3C定为标准。它使得客户端和服务器之间的数据交换变得更加简单,特别是允许服务端主动向客户端推送数据。实时性更高:WebSocket技术可以实现实时通信,传输数据的延迟更低,因此可以更快地将数据传输到客户端。减少网络带宽的使用:通过建立一个持久化的连接,WebSocket减少了HTTP协议中每次请求和响应所需要的网络带宽。

Android_data的博客 5343

springboot 中websocket的使用

一.WebSocket简单介绍随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。我们知道,传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器...

lpfasd123的博客 2554

websocket+netty实时视频弹幕交互功能(Java版)

/*/@Override后台处理逻辑,接受到消息,写出到所有的客户端:/*** +/|/*/// 用于记录和管理所有客户端的channel@Override// 获取客户端传输过来的消息System.err.println(“收到消息:”+ content);System.err.println(“写出消息完成:”+content);

2401_84103616的博客 756

在Java中使用WebSocket

WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发,并于2011年成为标准。

小易 2万+

华为ITR流程实战指南:从设计到落地的全流程解析(附完整方案下载)

本文深度解析华为ITR流程从设计到落地的全流程实战指南。ITR不仅是高效处理客户问题的“救火”系统,更是驱动产品改进、预防问题的企业“免疫系统”。文章详细拆解了流程设计的四步走策略、三层技术支持体系的组织保障、以闭环改进为核心的考核激励,并探讨了如何借鉴其精髓,优化自身问题管理,实现从被动响应到主动服务的跨越。

y2z3a4b5c的博客 381

I2C通信协议SCL与SDA引脚特性:核心要点总结

深入讲解I2C通信协议中SCL和SDA引脚的工作机制与电气特性,帮助理解i2c通信协议的稳定传输原理,掌握上拉电阻配置与信号时序控制要点。

weixin_42103128的博客 2742

WebSocket(java版)服务示例

WebSocket 是一种基于 TCP 的全双工通信协议,核心作用是解决传统 HTTP 协议 “请求 - 响应” 模式的局限性,实现 客户端与服务器之间的实时、双向、低延迟数据传输。

不畏惧被人讨厌而是勇往直前,不随波逐流而是激流勇进,这才是对人而言的自由。 2392

Synopsys Sentaurus TCAD新手教程:从零开始仿真trench MOSFET(附完整代码解析)

本文提供Synopsys Sentaurus TCAD新手教程,详细讲解从零开始仿真trench MOSFET的全过程,包括环境搭建、外延生长、沟槽刻蚀、栅极形成等关键步骤,并附完整代码解析。通过实际案例帮助半导体工程师掌握Sprocess操作技巧,优化工艺参数设置,提升仿真效率。

weixin_30505225的博客 223

websocket java版

websocket基本概念,自行百度,直接上demo java代码 @ServerEndpoint("/websocket") public class Test { @OnMessage public void onMessage(String message, Session session) throws IOException, InterruptedE

j15221024030的博客 369

一款值得关注的开源企业管理ERP系统

盒木ERP是一款开源的现代化企业管理系统,采用前后端分离架构,后端基于Python+Django,前端使用Vue+Ant Design。系统涵盖采购、销售、库存、财务等核心业务模块,支持移动端操作和PDA扫码。具有开源免费、技术先进、功能完善等特点,适合中小企业使用或二次开发。项目提供详细部署指南,支持Docker容器化部署,是学习ERP系统开发和企业数字化转型的优秀选择。

1110

避坑指南:CST粒子工作室Track Solver常见的5个参数设置错误

本文深入剖析了CST粒子工作室中Track Solver在电子枪仿真时常见的5个关键参数设置错误,包括空间电荷模型选择、发射源定义、材料边界处理、监视器配置及求解器稳定性设置。通过对比错误与正确做法,帮助用户避开陷阱,确保粒子追踪仿真的物理准确性与数值稳定性,从而获得更精准的电子枪仿真结果。

dapp9builder的博客 491

【简单易懂】SSE 和 WebSocket(Java版)

一文搞懂:SSE和WebSocket的区别和编程实现

多学、多想、多做 1937

【DeepSeek开发入门】DeepSeek API 开发初体验

在人工智能蓬勃发展的时代,DeepSeek作为一款功能强大的AI大模型,为开发者提供了丰富的接口和便捷的开发体验。本文将基于DeepSeek的几个关键接口,带你快速入门,开启DeepSeek开发的探索之旅。通过本文,你已经初步了解了DeepSeek开发中几个重要接口的使用方法,包括列出模型、对话补全和查询余额接口,以及开发过程中的常见问题及解决办法。这是你踏入DeepSeek开发领域的第一步。在后续的学习中,你可以深入研究模型的参数调优,探索不同模型在各种场景下的应用,如利用模型实现更复杂的推理对话功能。

寻道AI,探索AI无限可能! 2764

Java版 WebSocket实现消息推送【保姆来了!】

WebSocket实现消息推送,一对一,一对多

weixin_53059814的博客 8067

8、Windows 部署ollama

一个本地运行大模型的集成框架,目前主要针对主流的LLaMA架构的开源大模型设计,通过将模型权重、配置文件和必要数据封装进由Modelfile定义的包中,从而实现大模型的下载、启动和本地运行的自动化部署及推理流程。此外,Ollama内置了一系列针对大模型运行和推理的优化策略,目前作为一个非常热门的大模型托管平台,已被包括LangChain、Taskweaver等在内的多个热门项目高度集成。

Andy_shenzl的博客 1134

手把手教你学Simulink--基于电能质量与无功补偿的场景实例:统一电能质量调节器(UPQC)的联合控制仿真

在现代电力系统中,电能质量问题有源电力滤波器(APF)→ 治理谐波与无功动态电压恢复器(DVR)→ 补偿电压暂降/暂升静止无功发生器(SVG)→ 无功补偿与电压支撑而统一电能质量调节器(Unified Power Quality Conditioner, UPQC)是一种集串联补偿与并联补偿于一体的全能型电能质量治理装置✅ 电压类问题:暂降、暂升、不平衡、闪变✅ 电流类问题:谐波、无功、三相不平衡✅ 实现双向有功交换(储能型)串联单元(DVR功能):串联于线路,控制电源侧电压质量并联单元。

MHD0815的博客 240

Java版WebSocket消息推送系统搭建

Java版WebSocket消息推送系统搭建 最近在做消息推送,网上查了一些资料,开始想的是用MQ来做,后面发现用WebSocket来做的话感觉应该要简单点,话不多说,准备撸代码。 后端核心代码 /** * 监听器类:主要任务是用ServletRequest将我们的HttpSession携带过去 * @author Monkey * @date 2020-05-23 */ @Component public class RequestListener implements ...

monkey的专栏 1030

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

websocket Java Programming注解版及配置

1、前言一直没有怎么做过前端的东西,但是最近的项目中,前端人员奇缺,公司又不安排新的人员进入,所以我这个后台开发人员只能拉过来坐前端了,前段的东西感觉一大堆,CSS,js自不必说,HTML生态圈就有很多的技术要去学习,好吧,那就一个一个的学习整理啦,先来说说最近这个项目的前端用到什么技术吧。1、Restful:DropWizard这个很简单,两天基本上就能拿下2、Js Framework :Ang...

u011191463的专栏 378

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

java socket 推送机制_Java整合WebSocket实现实时推送(注解版)

Java整合WebSocket实现实时推送(注解版)发布时间:2018-06-05 09:49,浏览次数:1113, 标签:JavaWebSocket第一次写博客,备份下代码,顺便给需要的同学看看,网上也有很多Java整合webSocket的例子,大多自己写个类继承WebSocketConfigurer ,直接使用注解的比较少,我也看了很多写的运行有问题,要么代码关键部分缺少,想着自己弄一个好了...

weixin_35559171的博客 1088

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

java实现websocket服务器,java版的WebSocket测试服务器

这是一个封装好的WebSocket服务器,通过简单的扩展就可以实现基于websocket的服务。写这个工具的主要目的是为了用于方便websocket应用的前端和服务器同时开发。比如做HTML5游戏一般都是服务器和客户端同时开发。在开发之前最重要的就是制定通信协议,但游戏客户端在开发时可能需要调用接口,此时如果服务器端还未实现的话,就可能影响客户端的开发工作,用这个就可以解决问题。可以在开发游戏客户...

weixin_39915721的博客 1165

java实时推送前端数据_Java整合WebSocket实现实时推送(注解版)

第一次写博客,备份下代码,顺便给需要的同学看看,网上也有很多Java整合webSocket的例子,大多自己写个类继承WebSocketConfigurer ,直接使用注解的比较少,我也看了很多写的运行有问题,要么代码关键部分缺少,想着自己弄一个好了,这个版本在网上某些大佬的基础上实现的,基础代码重复写没意义。1.加入websocket依赖包org.springframeworkspring-we...

weixin_32290249的博客 2959

Java实现WebSocket客户端和服务端(简单版)

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。WebSocket 是独立的、创建在 TCP 上的协议。

感谢阅读 1万+

java socket 推送_Java版WebSocket 实现消息推送

# web socket是什么?WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,允许服务器主动发送信息给客户端。## 用途实时Web应用的解决方案,实现Web的实时通信。说的再直白点,html的消息推送。假如你有一个页面,数据不定期更改,通常的做法就是轮询,客户端不停地向服务器请求最新的数据。当有了web socket,数据变动时 ...

weixin_31129821的博客 262

Java整合WebSocket实现实时推送(注解版)

第一次写博客,备份下代码,顺便给需要的同学看看,网上也有很多Java整合webSocket的例子,大多自己写个类继承 WebSocketConfigurer ,直接使用注解的比较少,我也看了很多写的运行有问题,要么代码关键部分缺少,想着自己弄一个好了,这个版本在网上某些大佬的基础上实现的,基础代码重复写没意义。1.加入websocket依赖包 &lt;!-- WebSocket --&gt...

三步两步走 3万+

WebSocket 从零到能跑:Java 开发者版

WebSocket 是全双工长连接协议,解决了 HTTP 轮询的延迟和资源浪费问题。在 Spring Boot 中,通过开启,注册处理连接、消息、关闭三个核心事件。生产环境要注意线程安全(ConcurrentHashMap)、心跳保活、连接数限制和鉴权。我们在牧原 MES 项目中用 WebSocket 实现了传感器异常数据的实时推送,看板页面毫秒级收到告警。

2401_83135864的博客 365
上一篇: 微信支付V3 生成平台证书
下一篇: 一、GNU编译工具的安装和使用
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值