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

WebSocket和Java相关推荐

  1. jdeveloper_在JDeveloper 12.1.3中为WebSocket使用Java API

    jdeveloper 介绍 最新版本的JDeveloper 12c(12.1.3.0)和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能. 其中之一是对用于WebS ...

  2. Websocket实现Java后台主动推送消息到前台

    写在前面 需求: 项目测试, 缺少用户登录失败给admin推送消息, 想到这个方式, 当用户登录失败时, admin用户会在页面看到咣咣乱弹的alert. 正文 pom.xml <!-- web ...

  3. js java socket_js使用WebSocket,java使用WebSocket

    创建java服务端代码 import java.net.InetSocketAddress; import org.java_websocket.WebSocket; import org.java_ ...

  4. .jdeveloper_在JDeveloper 12.1.3中为WebSocket使用Java API

    .jdeveloper 介绍 最新版本的JDeveloper 12c(12.1.3.0)和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能. 其中之一是对用于Web ...

  5. websocket实现java服务端与js端通信

    1,文件目录如下: 2,发布路径为:ip+端口+项目+endpoint 3,项目下载路径 https://files.cnblogs.com/files/javadongx/websocket.rar ...

  6. springBoot集成websocket报java.lang.IllegalStateException: Failed to register @ServerEndpoint class:错误

    搜了很多答案,大致有以下几种解决办法,如果有类似错误,大家可以按下面几类错误对照检查一下: 1. @ServerEndpoint("/webSocket/message/{xxx}/{xxx ...

  7. Java后端WebSocket的Tomcat实现

    转自: http://blog.chenzuhuang.com/archive/28.html http://www.cnblogs.com/xdp-gacl/p/5193279.html 一.Web ...

  8. Java Websocket实例【服务端与客户端实现全双工通讯】

    Java Websocket实例[服务端与客户端实现全双工通讯] 现很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP ...

  9. java websocket 上传大文件,使用java websocket API和Javascript上传文件

    我正在学习websocket并且已经使用websocket / json完成了聊天程序.但我坚持上传ATM的文件.任何建议&回答会很感激. 服务器端: package websocket; i ...

最新文章

  1. 解决:“Word遇到问题需要关闭。我们对此引起的不便表示抱歉” 的问题
  2. python——模块
  3. python筛选数据求均值_Python Pandas实现数据分组求平均值并填充nan的示例
  4. gtk linux 升级_Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)
  5. IOC容器特性注入第六篇:利用MVC注入点,把容器启动
  6. 遍历字典时用与不用iter的区别
  7. ppt 母板 如何修改你的背景图片
  8. php查询qq等级,php仿QQ等级太阳显示函数_php
  9. 函数/极限/导数的概念辨析
  10. 决战平安京解包--专有模型格式转换成PMX
  11. java按照模板导出word 文档
  12. C#时间格式转换问题(12小时制和24小时制)
  13. 分布式操作系统,批处理,分时,实时操作系统
  14. android 自动获取短信验证码
  15. 《驯服烂代码》第一章
  16. CodeForce 597ADivisibility
  17. 安装程序无法创建新的系统分区或者无法识别
  18. Spring项目整合WebService服务遇到问题记录
  19. PDF密码忘记了,如何找回口令密码
  20. java 静态链接_java如何调用静态链接库里面的函数?

热门文章

  1. java流与文件——java生成解压缩文件(夹)
  2. java记录类型_Java中的记录类型
  3. java锁_Java锁
  4. 程序中抛出空指针异常_从Java应用程序中消除空指针异常
  5. java中无限大_Java 9中的无限集
  6. 拼图登陆拼图二维码验证_另一个拼图观点
  7. 本地运行flowable_在CockroachDB上运行Flowable
  8. kafka 发布订阅_在Kafka中发布订阅模型
  9. java工程引入scala_引入ReactiveInflux:用于Scala和Java的无阻塞InfluxDB驱动程序,支持Apache Spark...
  10. openshift_OpenShift上的Java EE工作流(技术提示#64)