Bozhidar Bozhanov是Ontotext AD的高级软件工程师,拥有多年的从业经验,也是stackoverflow上的活跃用户。他精通于Java与Java技术栈,如Spring、JPA、JavaEE等,同时还是http://computoser.comhttp://welshare.com的创始人。曾开发过爱立信的项目、保加利亚电子政务项目以及大型招聘平台等。近日Bozhidar撰文谈到了WebSocket与Java,并给出了相应的代码示例。Bozhidar在文中详细分析了WebSocket的原理、适用范围,以及如何通过Java来使用WebSocket。

WebSocket是一个很酷的新技术,可以实现浏览器与服务器之间实时、双向的通信,几乎没有任何额外的代价。我这里要做的事情就是提供一个非常简洁,但却内容丰富的概览,介绍如何开始使用这门技术。首先读者需要了解如下一些事情:

  • 首先在浏览器与服务器之间需要开启一个TCP Socket连接,每一方都可以向对方发送消息(比如说,服务器可以在有数据时将其推送出去,无需使用轮询、长轮询、iframes等技术)。
  • 并不是所有浏览器都支持WebSocket技术,IE 10是首个支持WebSocket的IE版本,Android依然还存在着一些问题。幸好有SockJS,在不支持WebSocket的情况下,它会退回到其他的推送技术。
  • 并不是所有的代理服务器都支持或是允许WebSocket,因此这时还是需要退回到其他的推送技术。
  • WebSocket适合于游戏、交易型应用,事实上,它适合于任何服务器要向浏览器推送数据的场景。
  • Java有标准API(JSR-356),你可以在服务端通过它来处理WebSocket连接。
  • Spring在Java API的基础之上提供了一个API。对于Spring提供的支持来说,好消息是它对SockJS提供了服务器端的支持,你也可以毫无压力地使用依赖注入。Spring还对消息驱动的架构提供了STOMP支持。上面的两篇Spring文章都给出了GitHub上示例项目的链接,我强烈建议大家看看。
  • 长久以来,Atmosphere框架一直是服务器推送技术的解决方案。这里是WebSocket上手指南。另外,Cometd也提供了WebSocket支持

在给出具体的示例代码前,我首先来介绍一下Socket的生命周期,包括客户端的与服务器端的:

  1. 浏览器发出一个HTTP请求,带有一个特殊的Upgrade头,其值是“websocket”。
  2. 如果服务器能够“理解”WebSocket,那么它会使用状态101进行应答——交换协议。从现在开始,我们就不再使用HTTP了。
  3. 当服务器接收这个TCP Socket连接后,一个初始化方法会得到调用,当前的WebSocket Session会被传递进来。每个Socket都有唯一一个Session id。
  4. 当浏览器向服务器发送消息时,另一个方法会得到调用,你在这里获得Session与消息负载。
  5. 根据某个负载参数,应用代码会执行一个动作。负载的格式完全取决于开发者。一般来说会使用JSON序列化的对象。
  6. 当服务器需要发送消息时,它需要获得这个Session对象,然后通过它来发送消息。
  7. 当浏览器关闭连接时,服务器会得到通知,这样它就可以清理与特定Session关联的一些资源了。

目前,还没有任何一个API或框架能够支持基于注解的路由。Java API支持基于注解的端点处理器,不过每个连接URL需要一个类来处理,通常情况下,你希望在单个连接上执行多个操作。也就是说,你连接到ws://yourserver.com/game/,然后想要传递“joinGame”和“leaveGame”等消息。类似地,服务器需要发送回多种类型的消息。我使用了枚举来实现这一点,枚举中包含了所有可能的动作与事件类型,然后使用switch来确定该调用哪一个。

因此,我决定为我的算法音乐作曲家开发一个简单的游戏。它使用了Spring API,感兴趣的读者可以看看这个介绍,这是我在公司所做的一次演讲。下面是一些示例代码:

@Component
public class GameHandler extends WebSocketHandlerAdapter {
private Map

下面来看一个示例场景,其中服务器需要向客户端发送消息。这就好比一个玩家加入了游戏一样,这时其他所有玩家都会收到有新人加入的通知。系统中的中心类是Game,它拥有一个玩家列表。如你所见,一个Player包含了一个对WebSocket Session的引用。这样,当新的玩家加入时,下面的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);
}
}

从服务器向浏览器发送消息可能还需要一个调度job进行触发。

关键在于你维护了一个所有已连接的浏览器列表,这样就可以向回发送信息了。这个列表可以是个静态属性,不过对于单例的Spring Bean来说就没必要这么做了。

现在,有两个重要的方面需要我们注意——安全与认证。这是来自于Heroku的一篇很不错的文章,对安全与认证进行了详细的介绍。如果还有其他敏感信息,你就应该使用wss(Websocket over TLS)了。你还应该在服务器端与客户端验证输入,而不应该依赖于Origin头,因为攻击者可以轻而易举地骗过浏览器。

认证可以依赖于HTTP Session cookie,不过显而易见的是,有些人更喜欢实现自己的类cookie工作流,从而获取一个短暂的令牌,它可以用于执行认证操作。

WebSocket使得DDD变得更加自然。你不必再处理贫血对象了,你的对象有各自的状态以及对这些状态的操作。与之相关的是,WebSocket应用的测试变得更加容易了。

在开发WebSocket应用时还有不少需要注意的事情。值得注意的是,你没有必要在任何地方都使用WebSocket,我将其限定在需要“推送”的场景下。

总的来说,WebSocket是一个很棒、很有趣的技术,它非常有希望灭掉所有采用hack手段实现的推送模拟技术。

原文来自于:http://www.infoq.com/cn/news/2013/12/websocket-and-java

转:WebSocket与Java的更多相关文章

  1. WebSocket实践——Java实现WebSocket的两种方式

    什么是 WebSocket? 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...

  2. js使用WebSocket,java使用WebSocket

    js使用WebSocket,java使用WebSocket 创建java服务端代码 import java.net.InetSocketAddress; import org.java_websock ...

  3. WebSocket实现Java后台消息推送

    1.什么是WebSocket WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. 2.实现原理 在实现 ...

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

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

  5. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  6. Java后端WebSocket的Tomcat实现

    转自:http://blog.chenzuhuang.com/archive/28.html 文章摘要随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5 ...

  7. Java用webSocket实现tomcat的日志实时输出到web页面

    原文:http://blog.csdn.net/smile326/article/details/52218264 1.场景需求 后台攻城狮和前端攻城狮一起开发时,经常受到前端攻城狮的骚扰,动不动就来 ...

  8. 基于Tomcat7、Java、WebSocket的服务器推送聊天室

    http://blog.csdn.net/leecho571/article/details/9707497 http://blog.fens.me/java-websocket-intro/ jav ...

  9. 【java】基于Tomcat的WebSocket转帖 + 自己理解

    网址:http://redstarofsleep.iteye.com/blog/1488639 原帖时间是2012-5-8,自己书写时间是2013年6月21日10:39:06 Java代码 packa ...

随机推荐

  1. [置顶] VC++界面编程之--使用分层窗口实现界面皮肤

    使用分层界面来实现界面皮肤的好处是:可以保证图片边缘处理不失真,且能用于异形窗口上,如一些不规则的窗口,你很难用SetWindowRgn来达到理想效果. 在很多情况下,界面的漂亮与否,取决于PS的制作 ...

  2. PHP中echo,print(),print_r()的区别

    echo是 php 语句, print和print_r是函数,语句没有返回值,函数可以有返回值(即便没有用)    print() 只能打印出简单类型变量的值(如int,string) print_r ...

  3. OPENCV第一篇

    了解过之前老版本OpenCV的童鞋们都应该清楚,对于OpenCV1.0时代的基于 C 语言接口而建的图像存储格式IplImage*,如果在退出前忘记release掉的话,就会照成内存泄露.而且用起来超 ...

  4. XP的定时关机命令?

    Windows XP的关机是由Shutdown.exe程序来控制的,位于Windows/System32文件夹中.如 果想让Windows 2000也实现相同的效果,能够把Shutdown.exe拷贝 ...

  5. 实例化讲解 RunLoop

    实例化讲解RunLoop 之前看过很多有关RunLoop的文章,其中要么是主要介绍RunLoop的基本概念,要么是主要讲解RunLoop的底层原理,很少用真正的实例来讲解RunLoop的,这其中有大部 ...

  6. H.264视频在android手机端的解码与播放(转)

    随着无线网络和智能手机的发展,智能手机与人们日常生活联系越来越紧密,娱乐.商务应用.金融应用.交通出行各种功能的软件大批涌现,使得人们的生活丰富多彩.快捷便利,也让它成为人们生活中不可取代的一部分.其 ...

  7. noip 2015 运输计划 (lca+二分)

    /* 95 最后一个点T了 qian lv ji qiong 了 没学过树剖 听chx听xzc说的神奇的方法 Orz 首先求出每个计划的路径长度 这里写的倍增 然后二分答案 对于每个ans 统计> ...

  8. My.Ioc 代码示例——避免循环依赖

    本文的目的在于通过一些示例,向大家说明 My.Ioc 支持哪些类型的依赖关系.也就是说,如何设计对象不会导致循环依赖. 在 Ioc 世界中,循环依赖是一个顽敌.这不仅因为它会导致 Ioc 容器抛出异常 ...

  9. 安装PHP过程中,make步骤报错:(集合网络上各种解决方法)

    安装PHP过程中,make步骤报错:(集合网络上各种解决方法) (1)-liconv -o sapi/fpm/php-fpm /usr/bin/ld: cannot find -liconv coll ...

  10. META http-equiv 大全

    META http-equiv 大全 HTTP-EQUIV类似于HTTP的头部协议,它回应给浏览器一些有用的信息,以帮助正确和精确地显示网页内容.常用的HTTP-EQUIV类型有: 1.Content ...