WebSocket Java Programming入门-1(annotated)

1、前言

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

1、Restful:DropWizard这个很简单,两天基本上就能拿下

2、Js Framework :AngularJS 这个JS库的确很酷,最近学习的过程中越来越喜欢这个东西了,打算以后再整理一些AngularJS的学习笔记和过程

3、前端和后端的通讯的方式不是那种request和response的方式,而是采用HTML5的WebSocket。

4、其他技术我就不一一列举了

在学习websocket的过程中我阅读了一下tomcat的websocket examples当然最重要的是阅读了一本比较不错的系统化的WEBSOCKET书,推荐给大家《JAVA WEBSOCKET PROGRAMMING》然后我尽力将自己学到的东西,尽可能通俗的详细地介绍一下,方便和大家交流。

2、环境配置

网上关于Websocket是什么的文章多如牛毛,我这里也就不用挨个去摘抄,先直接来一个比较直观的例子,本文中采用的是基于注解的方式,来演示一个Echo Server的实例

2.1、运行环境要求:

Tomcat版本必须在7.0.47版本以上才可以

JDK必须在1.7版本以上才可以

2.2、开发环境:(不做强制要求,根据个人的爱好,我只是列举一下我的开发环境)

Maven:3.0.4

IDE:Intellij IDEA

3、第一个基于注解的WebSocket Demo

好了,一切准备就绪,我们来看看下面的代码吧,然后我再一一说明其中的一些细节

3.1、 Maven的POM

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
        <artifactId>websocket</artifactId>
        <groupId>websocket</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>websocket-anotation</artifactId>
    <packaging>war</packaging>
    <name>websocket-anotation Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>websocket-anotation</finalName>
    </build>
</project>

其中我们引入了javax websocket的标准api接口,并且将其的scope设置成provided(tomcat容器已经自带了这个包,我们不需要重复发布,指定为provided的目的就是为了在编写代码的过程中使用而已)。

3.2、服务段代码:

package com.wangwenjun.websocket.annotation;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/hello")
public class HelloWorldServer {

    @OnMessage
    public String sayHello(String incomingMessage) {
        return "I got this(" + incomingMessage + ") so I am sending it back to you!";
    }

    @OnOpen
    public void open(Session session) {
        System.out.println("On Open---" + session.getBasicRemote());
    }

    @OnClose
    public void close() {
        System.out.println("Close.");
    }
}

其实这个例子中只要有一个方法被@OnMessage注解即可,其他的open和close 暂时可以忽略掉,Websocket的方式不仅可以和服务段传递文本信息也可以交互二进制的形式(InputStream),不仅可以返回字符串,也可以返回二进制流(OutputStream),而且还可以得到整个回话的引用如Session,也就意味着我们下面的方法都是合理的

@OnMessage
    public void test1(String test){
        //do nothing.
    }

    @OnMessage
    public void test2(InputStream inputStream){
        //do nothing.
    }

    @OnMessage
    public OutputStream test3(InputStream inputStream){
        //do nothing.
        return null;
    }

    @OnMessage
    public void test4(String text,Session session){
        //do nothing.
    }

等等诸如此类吧,都是可行的,好了我们说会刚才那个方法sayHello,该方法接受一个文本字符串,并且返回一个文本字符串,注解为OnMessage,表示它接受来自客户端的信息并且处理之。

3.3、客户端代码

<!DOCTYPE HTML>

<html>
<head>
    <title>WebSocket Learning Example(Hello World)</title>
    <script type="text/javascript">
        var ws;
        function init() {
            outputArea = document.getElementById("output");
        }

        function sayHello() {
            var url = "ws://localhost:8080/websocket-anotation/hello";
            writeMessageToScreen("Connecting to " + url);
            ws = new WebSocket(url);
            ws.onopen = function (event) {
                writeMessageToScreen("Connected.");
                var message=document.getElementById("message").value;
                doSend(message);
            }

            ws.onmessage = function (event) {
                writeMessageToScreen("Received message: " + event.data);
                ws.close();
            }

            ws.onerror = function (event) {
                writeMessageToScreen("Occur Error:<span style='color:red'>" + event.data + "</span>");
                ws.close();
            }
        }

        function doSend(message) {
            ws.send(message);
            writeMessageToScreen("Sent message: " + message);
        }

        function writeMessageToScreen(message) {
            var p = document.createElement("p");
            p.style.wordWrap = "break-word";
            p.innerHTML = message;
            outputArea.appendChild(p);
        }

        this.addEventListener("load", init, false);
    </script>
</head>
<body>
<h1>Hello World Server</h1>

<div style="text-align:left">
    <form action="#">
        <input type="text"  id="message" placeholder="Please enter your name."/>
        <input type="button" id="sender" value="PressMeToSend" onclick="sayHello()"/>
    </form>
</div>
<div id="output">
</div>
</body>
</html>

客户端的代码关于DOM的操作我用的是最元生的处理方式,并没有采用Jquery等对Dom支持特别好的第三方库,想必大家都能看得明白,我就不做更多的解释了,关键来说说WebSocket对象,websocket对象在JS宿主(浏览器)中并不是都被支持,IE就从第十个版本才开始支持的,如果你做的是一个互联网应用,没有办法强制让客户试用统一支持websocket对象的浏览器,你最好能够判断一下js环境是否支持websocket的对象,判断的方法也是非常简单,如下的几种方式都可以

//method 1
        if(window.WebSocket){

        }

        //method 2
        if("WebSocket" in window)
        {

        }

        //method 3
        if(window["WebSocket"]){

        }

好了,我们来说一下上面JS代码中的几个关键部分吧

 var url = "ws://localhost:8080/websocket-anotation/hello";

定义了Websocket ServerEndpoint的地址,记住协议是WS哦,不要像我一样第一次学习的习惯性的用http,最后的那个URI/hello是我们在我们的HelloWorldServer中用@ServerEnmdpoint注解的Value值,应该不难理解吧。

ws = new WebSocket(url);

创建一个WebSocket的对象,如果能够创建成功就可以使用我们的WebSocket了,不过更加严谨的做法应该是像我在前面所说的那样应该判断JS宿主环境是否支持WebSocket,否则下面的代码都会出现错误的。

WebSocket最美的地方有很多回调函数在里面,当发生相关的事情会被自动调用,如下面的代码就是注册相关的回调函数

ws.onopen = function (event) {
                writeMessageToScreen("Connected.");
                var message=document.getElementById("message").value;
                doSend(message);
            }

            ws.onmessage = function (event) {
                writeMessageToScreen("Received message: " + event.data);
                ws.close();
            }

            ws.onerror = function (event) {
                writeMessageToScreen("Occur Error:<span style='color:red'>" + event.data + "</span>");
                ws.close();
            }

第一个当成功连接之后会被调用,第二个是收到了来自ServerEndpoint的消息之后的回调,第三个是发生了错误会被回调,怎么样很爽吧。

最后一个比较关键的方法就是发送消息到服务端,但是不得不承认真的很简单,简单到就一行

ws.send(message);

4、发布

就这么简单,寥寥几行代码就可以实现一个最基本的客户端与服务端通讯的小程序,写到这里我们应该发布一下,看看运新多个效果如何,运行

mvn clean package命令,将web项目打包成一个war包 ,然后拷贝到你的tomcat webapps目录下面,当然你也可以安装tomcat自动部署插件,运行命令即可自动将war包发布到webapps下面去,感兴趣的可以自己尝试,我在这里就不做演示了,然后访问页面:http://localhost:8080/websocket-anotation/ 自己玩一把吧。

5、简单总结

Http是一个非持续连接协议,也就是说每一次的和服务器交互都是一个新的连接,我们可以理解为一个基于TCP的短连接协议,但是Websocket的出现,给Web开发人员多了一个长连接的选择,我们可以和服务端始终保持回话,并且接受来自服务端的信息,在互联网中,基于Websocket的应用越来越多了,学习掌握是很有必要的,在接下来还会继续进行更新,再说一遍《JAVA WEBSOCKET PROGRAMMING》这本书真的很好,而且只有两百多页,看完之后加以练习,相信你会精通WebSocket的使用的。

时间: 2024-08-13 15:35:40

WebSocket Java Programming入门-1(annotated)的相关文章

Java Annotation入门

Java Annotation入门作者:cleverpig 版权声明:本文可以自由转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明作者:cleverpig(作者的Blog:http://blog.matrix.org.cn/page/cleverpig)原 文:[http://www.matrix.org.cn/resource/article/44/44048_Java+Annotation.html]http://www.matrix.org.cn/resource/arti

Get your Advanced Java Programming Degree with these Tutorials and Courses

Getting started as a Java developer these days is quite straightforward. There are countless books on the subject, and of course an abundance of online material to study. 最近,入门成为一名java开发人员是非常简单的.有无相关的书籍,当然还有大量的在线资料可供学习 Of course, our own site offers

Java的入门基础知识

https://course.tianmaying.com/java-basic%2Bjava-environment#0 作者:David链接:https://www.zhihu.com/question/25255189/answer/86898400来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 这个教程将Java的入门基础知识贯穿在一个实例中,逐步深入,可以帮助你快速进入Java编程的世界.万事开头难,逐步跟着这个教程走一遍,对Java应该就会有一种入门的

WebSocket.之.基础入门-建立连接

WebSocket.之.基础入门-建立连接 1. 使用开发工具(STS.Eclipse等)创建web项目.如下图所示,啥东西都没有.一个新的web项目. 2. 创建java类.index.jsp页面.注意:web.xml未做任何改动. TestConfig.java 代码如下: 1 package com.charles.socket; 2 3 import java.util.Set; 4 5 import javax.websocket.Endpoint; 6 import javax.we

WebSocket.之.基础入门-前端发送消息

WebSocket.之.基础入门-前端发送消息 在<WebSocket.之.基础入门-建立连接>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 index.jsp 两个文件. 项目结构如下图: TestSocket.java 1 package com.charles.socket; 2 3 import javax.websocket.OnMessage; 4 import javax.websocket.OnOpen; 5 import javax.webs

WebSocket.之.基础入门-后端响应消息

WebSocket.之.基础入门-后端响应消息 在<WebSocket.之.基础入门-前端发送消息>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 index.jsp 两个文件. 项目结构如下: TestSocket.java 代码 1 package com.charles.socket; 2 3 import java.io.IOException; 4 5 import javax.websocket.OnMessage; 6 import javax.w

WebSocket.之.基础入门-断开连接处理

ebSocket.之.基础入门-断开连接处理 在<WebSocket.之.基础入门-后端响应消息>的代码基础之上,继续更新代码.代码只改动了:TestSocket.java 和 index.jsp 两个文件. 先说问题: 当前后端建立连接之后,如果此时关闭浏览器,或者点击浏览器的回退.只要退出了建立连接的页面.后台程序是会报错的.分别如下图所示: 正常建立连接页面: 现在退出当前建立连接的页面,后台日志如下所示: 1 当前session的id是:0 2 从前端页面传过来的数据是:早上好.. 3

Java反射入门

Java这么多高灵活性,很多都是利用反射来实现的,所谓的反射是指,编译期间完全未知的classes,运行时,对任一个类(根据类名-字符串),能够知道这个类的所有属性和方法:对于任一个对象,都能够调用它的任意一个方法和属性. 简而言之,Java反射机制主要提供了以下功能: ?  在运行时判断任意一个对象所属的类:obj.getClass() ?  在运行时构造任意一个类的对象: ?  在运行时判断任意一个类所具有的成员变量和方法: ?  在运行时调用任意一个对象的方法. 下面我们先用一个简单小例体

《Java从入门到放弃》文章目录

转眼半个月过去了,不知不觉也写了10篇博客,突然发现所有的目录都没有纯列表的展示,所以特意写一个目录篇,来记录该系列下所有的文章. 当然,因为现在还没有写完,所以先按时间顺序排列,等相关内容都写完后,再按学习顺序来整理. <Java从入门到放弃>入门篇:XMLHttpRequest的基本用法 <Java从入门到放弃>入门篇:Struts2的基本访问方 <Java从入门到放弃>入门篇:Struts2的基本访问方式(二) <Java从入门到放弃>入门篇:Stru