WebSocket和Java

WebSocket是一项很酷的新技术,它允许浏览器与服务器之间进行实时双向通信,而几乎没有开销。 我在这里想要做的是,提供一个非常简洁但足够全面的概述,以介绍如何开始使用该技术。 因此,从以下几件事开始:

  • 在浏览器和服务器之间打开了一个tcp套接字连接,并且各方可以向另一方发送消息(即,只要有可用,服务器就可以推送数据-无需轮询,长时间轮询,iframe等)。
  • 并非所有浏览器都支持它-IE 10是第一个支持它的IE版本,Android仍然存在问题。 幸运的是,如果不支持WebSocket,则可以使用SockJS ,它可以回溯到其他推式仿真。
  • 并非所有代理服务器都支持/允许它,因此可能需要再次进行回退
  • 适用于游戏,交易应用程序,以及实际上任何需要服务器将数据推送到浏览器的事物
  • Java具有标准的API(JSR-356) ,您可以在服务器上使用它来处理WebSocket连接。
  • Spring在Java API之上提供了一个 API。 spring支持的好处是它具有对SockJS的服务器端支持,您可以轻松使用依赖注入。 Spring还为消息驱动的体系结构提供了STOMP支持 。 这两篇Spring文章都包含指向我推荐的GitHub示例项目的链接。

在继续一些示例代码之前,这里是套接字的生命周期,包括客户端和服务器(假设上述API之一):

  1. 浏览器发送带有特殊升级头的HTTP请求,其值是“ websocket”。
  2. 如果服务器“说” webocket,它将以状态101(交换协议)答复。 从现在开始,我们不再使用HTTP
  3. 当服务器接受tcp套接字连接时,将调用初始化方法,并在其中传递当前的websocket会话。 每个套接字都有一个唯一的会话ID。
  4. 每当浏览器向服务器发送消息时,就会在获取会话和消息有效负载的地方调用另一种方法。
  5. 基于某些有效负载参数,应用程序代码执行几种操作之一。 有效负载格式完全取决于开发人员。 但是,通常,它是一个JSON序列化的对象。
  6. 每当服务器需要发送消息时,它都需要获取会话对象,并使用它来发送消息。
  7. 当浏览器关闭连接时,会通知服务器,以便它可以清除与特定会话相关的任何资源。

当前,没有API或框架支持基于注释的路由。 Java API支持基于注释的终结点处理程序,但是它为每个连接URL提供一个类,并且通常您希望在单个连接上执行多个操作。 即,您连接到ws://yourserver.com/game/,然后要传递“ joinGame”,“ leaveGame”消息。 同样,服务器需要发回不止一种消息。 我的实现方式是通过一个枚举,包含所有可能的动作/事件类型,并使用switch构造确定要调用的内容。

因此,我决定为我的算法音乐作曲家制作一个简单的游戏 。 它使用的是Spring API。 这是我在我所工作的公司中所做的相关演示的幻灯片 。 下面是一些示例代码:

@Component
public class GameHandler extends WebSocketHandlerAdapter {private Map players = new ConcurrentHashMap<>();private Map playerGames = new ConcurrentHashMap<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {Player player = new Player(session);players.put(session.getId(), player);}@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {leaveGame(session.getId());
}@Override
protected void handleTextMessage(WebSocketSession session, TextMessage textMessage) throws Exception {try {GameMessage message = getMessage(textMessage); //deserializes the JSON payloadswitch(message.getAction()) { case INITIALIZE: initialize(message, session); break;case JOIN: join(message.getGameId(), message.getPlayerName(), session); break;case LEAVE: leave(session.getId()); break;case START: startGame(message); break;case ANSWER: answer(message, session.getId()); break;}} catch (Exception ex) {logger.error("Exception occurred while handling message", ex);}
}

让我们看一个示例服务,服务器需要在其中向客户端发送消息。 让我们以一个玩家加入游戏为例,而所有其他玩家都需要收到新的通知。 系统中的核心类是Game,其中包含玩家列表,并且如您所见,Player包含对WebSocket会话的引用。 因此,当玩家加入游戏时,将调用以下Game方法:

public boolean playerJoined(Player player) {for (Player otherPlayer : players.values()) {otherPlayer.playerJoined(player);}players.put(player.getSession().getId(), player);return true;
}

然后player.playerJoined(..)通过基础连接发送一条消息,通知浏览器新玩家加入:

public void playerJoined(Player player) {GameEvent event = new GameEvent(GameEventType.PLAYER_JOINED);event.setPlayerId(player.getSession().getId()); event.setPlayerName(player.getName());try {session.sendMessage(new TextMessage(event.toJson()));} catch (IOException e) {new IllegalStateException(e);}}

从服务器向浏览器发送消息也可能由计划的作业触发。

关键是要保留所有已连接浏览器的列表,以便可以将信息发送回去。 该列表可以是一个静态字段,但是对于单例spring bean,则不需要。

现在,两个重要方面–安全性和身份验证。 这是Heroku的一篇不错的文章 ,同时讨论了两者。 如果有任何敏感内容,您应该首选wss(相对于TLS,它是websocket)。 您还应该在两端验证您的输入,并且不应该依赖Origin标头,因为攻击者可能很容易欺骗浏览器。

身份验证可以依赖于HTTP会话cookie,但是显然,有些人更喜欢实现自己的类似于cookie的工作流,以获取短暂的令牌,该令牌可用于执行经过身份验证的操作。

WebSocket使DDD变得自然。 您不再需要使用贫血对象-您的对象具有各自的状态,并且在该状态下执行操作。 与此相关的是,websocket应用程序更易于测试。

这是开发WebSocket应用程序时要记住的一般事项。 请注意,您不必在所有地方都使用WebSocket –我将其仅限于需要“推送”的功能。

总体而言,WebSocket是一项很好的有趣技术,有望淘汰所有hacky推送仿真。

参考:来自Java出现日历博客的JCG合作伙伴 Glamdring的WebSocket和Java 。

翻译自: https://www.javacodegeeks.com/2013/12/websocket-and-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/365760.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网页顶部进度条-NProcess.js

背景 有些网站&#xff0c;比如github上在查看项目文件夹层级时会在网页顶部出现一个 进度条&#xff0c;虽然是PC端却有一种移动端体验&#xff0c;个人认为可以提升使用体验&#xff0c;经查阅相关资料后&#xff0c;找到一个NProgress.js全站进度条插件 示例 在使用vue开发S…

点击图片放大至原始图片大小

有些时候为了排版的整洁&#xff0c;页面展示的图片不得不都是限定宽高的&#xff0c;如果想要点击图片放大至原始大小进行预览&#xff0c;再次点击回到原来样子&#xff0c;就要用到下面的代码了&#xff1a; var _w parseInt($(window).width());//获取浏览器的宽度$("…

ft服务器设置传输协议,ft服务器设置成主动模式

ft服务器设置成主动模式 内容精选换一换如果您选择使用SFS Turbo实现文件共享存储&#xff0c;此章节操作可跳过&#xff0c;您可以参见《SAP HANA用户指南》中的“格式化磁盘”章节&#xff0c;挂载Backup卷。NFS Server磁盘需要格式化&#xff0c;并挂载到相应的目录后&#…

c语言将字符串按空格分割_以空格作为分隔符的字符串三角形C语言

这是一个独特的三角形&#xff0c;它与所有其他三角形不同&#xff0c;它以这种方式打印由空格分隔的单词。我在寻找的答案不存在于任何其他问题中&#xff0c;已经检查过了。以空格作为分隔符的字符串三角形C语言输出应该是这样的这这是这是这是最好的这是最好的办法这是最好的…

制作逻辑卷快照

逻辑卷快照的功能是将逻辑卷的数据保存备份、以及快速的数据恢复 查看逻辑卷的详细信息&#xff1a;vgdisplay 对vg01卷组的lv01逻辑卷做一个名称为SNAP而大小为150M的逻辑卷快照: lvcreate -L 150M -s -n SNAP /dev/rhcsa/vo 查看逻辑卷和快照的信息: lvs 在逻辑卷中…

使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载

Primefaces数据表惰性分页有效&#xff0c;但是在Web上使用Criteria搜索完整示例后&#xff0c;我感到非常沮丧。 所以我混合了来自 http://stackoverflow.com/questions/13972193/how-to-query-data-for-primefaces-datatable-with-lazy-loading-and-pagination http://www.…

mysql text字段导出_Mysql数据库的各种命令:

一、连接MYSQL格式&#xff1a; mysql -h主机地址 -u用户名 -p用户密码1、连接到本机上的MYSQL。 首先打开DOS窗口&#xff0c;然后进入目录mysqlbin&#xff0c;再键入命令mysql -u root -p&#xff0c;回车后提示你输密码. 注意用户名前可以有空格也可以没有空格&#xff0c;…

微信浏览器返回刷新,监听微信浏览器返回事件,网页防复制,移动端禁止图片长按和vivo手机点击img标签放大图片

以下代码都经过iphone7&#xff0c;华为MT7 &#xff0c;谷歌浏览器&#xff0c;微信开发者工具&#xff0c;PC端微信验证。如有bug&#xff0c;还请在评论区留言。 demo链接&#xff1a;https://pan.baidu.com/s/1c35mbjM 密码&#xff1a;5yyf 1.移动端微信浏览器返回刷新…

access数据库为什么一直登陆_为什么要养成用Access数据库保存数据的习惯?

我是宇哥&#xff0c;专门教数据库的&#xff0c;学办公软件的女同学没有不认识我的。一、今天强调一下&#xff1a;为什么要养成用标准数据库保存数据的习惯&#xff5e;其实制造业企业&#xff0c;都更倾向于用Access数据库保存日常数据&#xff0c;尤其是一些高端制造业&…

服务器主板北桥芯片组有哪些,主板芯片组_目前的主板芯片组都有哪些?

目前主流的芯片组有&#xff1a;Intel(英特尔)的、、、。AMD(超微)的、、、。nVidia的、、。芯片组就相当于主板的大脑&#xff0c;主板是什么芯片组决定了主板可以装什么处理器。因为主板芯片分为北桥芯片(离处理器近的)与南桥芯片(离处理器远的)&#xff0c;它们一般是成对出…

快速安装puppeteer (跳过安装Chromium)

npm i --save puppeteer --ignore-scripts 设置镜像下载 npm config set PUPPETEER_DOWNLOAD_HOSThttps://npm.taobao.org/mirrors npm install --save puppeteer 转载于:https://www.cnblogs.com/jso0/p/10336205.html

python地板除与除法的区别_“地板除”还是“取整除”?地板除和天花板除floor division和ceil devision...

上一篇文章知识点太多&#xff0c;我需要一一查看理解。 在运算符 ➡ 算数运算符 ➡ 操作符 ➡ // 整除&#xff08;地板除&#xff09; 3//4 为什么叫地板除&#xff1f; 向下取整除&#xff0c;就是地板除 floor division 向上取整除&#xff0c;就是天花板除&#xff0c;cei…

运行,JUnit! 跑!!!

JUnit与JavaScript和SVN一起是程序员经常开始使用的一些技术&#xff0c;甚至没有读过一篇博客文章&#xff0c;更不用说一本书了。 也许这是一件好事&#xff0c;因为它们看起来足够简单且易于理解&#xff0c;因此我们无需任何手册即可立即使用它们&#xff0c;但这也意味着它…

css3图形绘制

以下几个例子主要是运用了css3中border、bordr-radius、transform、伪元素等属性来完成的&#xff0c;我们先了解下它们的基本原理。 border&#xff1a;简单的来说border语法主要包含&#xff08;border-width、border-style、border-color&#xff09;三个属性。 „ border-t…

vueh5调用摄像头拍照_潜望式拍照5G手机盘点:售价相差数千元 究竟怎么选?

【dogkeji-科技犬】最近很多网友询问科技犬&#xff0c;目前支持50X潜望式长焦手机都有哪些&#xff0c;可否进行相关手机的推荐&#xff0c;今天就应大家的需求来盘点一下&#xff0c;给各位网友一些参考。推荐一&#xff0c;三星 Galaxy S20 U三星Galaxy S20 5G系列不仅搭载了…

09 事件对象

上篇介绍完我们js的事件流的概念之后&#xff0c;相信大家对事件流也有所了解了。那么接下来我们看一下jquery的事件操作。 在说jquery的每个事件之前&#xff0c;我们先来看一下事件对象 事件对象 Event 对象代表事件的状态&#xff0c;比如事件在其中发生的元素、键盘按键的状…

使用Struts2,Hibernate和MySQL创建个人MusicManager Web应用程序的研讨会

概述&#xff1a; 在本研讨会教程中&#xff0c;我们将使用Struts 2&#xff0c;Hibernate和MySQL数据库开发一个个人音乐管理器应用程序。 该Web应用程序可用于将您的音乐收藏添加到数据库中。 我们将显示用于添加唱片的表格&#xff0c;并在下面显示所有音乐收藏。 通过单击“…

链表快速排序python_Python一行代码实现快速排序的方法

今天将单独为大家介绍一下快速排序&#xff01; 一、算法介绍 排序算法&#xff08;Sorting algorithm&#xff09;是计算机科学最古老、最基本的课题之一。要想成为合格的程序员&#xff0c;就必须理解和掌握各种排序算法。其中"快速排序"&#xff08;Quicksort&…

自定义滚动条样式

啥都不说先看图: 注: 只适合chrom,不适用IE和fireFox 下面展示代码: 1 <html lang"en">2 <head>3 <meta charset"UTF-8">4 <title>CSS3自定义滚动条-轩枫阁</title>5 <style>6 header7 {8 font-family: …

解决zsh下ls命令无高亮颜色问题

问题原因因为本人比较菜不清楚, 但总归瞎弄解决了, 做个记录 解决方法 进入用户目录下的.bashrc(~/.bashrc), 寻找ls相关配置找到后将相关配置复制到.zshrc(~/.zshrc)中如果找不到的话, 可以复制我找到的直接复制. if [ -x /usr/bin/dircolors ]; thentest -r ~/.dircolors &am…