WebSocket 从入门到精通 -- Spring boot服务端客户端 -- HTML客户端

注意:学习本文章一定要打开自己的开发工具,代码中有详细的解释。电脑不在身边建议先收藏,方便日后观看。最后祝大家技术突飞猛进,早日拿到心仪的offer。

基础讲解

Spring Boot 服务端

这里我们需要先介绍几个注解

注解名称说明
@ServerEndpoint指定的客户端请求的URI
@OnOpen建立连接成功调用
@OnClose关闭连接时调用
@OnMessage收到客户端消息后调用的方法
@OnError发生错误触发

Spring Boot 客户端

注解名称说明
@OnOpen建立连接成功调用
@OnClose关闭连接时调用
@OnMessage客户端接收服务端数据时触发
@OnError发生错误触发

创建步骤:

  1. 自定义一个类继承WebSocketClient
  2. 声明一个带参的构造方法(参数为ServerEndpoint指定的URI)
    例如:ws://localhost:8080/websocketdemo
  3. 将参数通过super(serverUri)传给父类的构造方法;
  4. 请看下方详细代码

HTML 客户端

//创建WebSocket对象
var websocket = new WebSocket("ws://localhost:8080/websocketdemo");

四大监听参数

事件名称调用方式触发监听事件
openwebsocket.onopen连接建立时触发
messagewebsocket.onmessage客户端接收服务端数据时触发
errorwebsocket.onerror通信发生错误时触发
closewebsocket.onclose连接关闭时触发

请求方法

方法说明
websocket.send()像服务端发送数据
websocket.close()关闭连接

基础示例代码

Spring Boot服务端

maven引入依赖

<!--WebSocket核心依赖包-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.4.1</version>
    <scope>compile</scope>
</dependency>

开启服务端

这里主要就是四大监听参数,以及设置URI地址。

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

//这里的服务地址为:ws://localhost:8080/websocketdemo
@ServerEndpoint("/websocketdemo")
@Component
public class MyDemoServer {

    /**
     * 百度搜索:程序员小哲
     * 建立连接成功调用
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接成功!");
    }

    /**
     * 百度搜索:程序员小哲
     * 关闭连接时调用
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        System.out.println("关闭连接!");
    }

    /**
     * 百度搜索:程序员小哲
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(Session session,String message) {
        System.out.println("接收消息:"+message);
    }

    /**
     * 百度搜索:程序员小哲
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("连接异常:{}"+throwable);
    }

}

自动注册@ServerEndpoint注解

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     * 这个Bean会自动注册@ServerEndpoint
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

Spring Boot 客户端

稍微复杂,可以使用HTML客户端

maven引入依赖

<!--WebSocket核心依赖包-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.4.1</version>
    <scope>compile</scope>
</dependency>

创建一个类,继承WebSocketClient

添加一个带参构造

在这里插入图片描述

重写下面四个方法

在这里插入图片描述

直接copy源码
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;

public class MyWebSocketClient extends WebSocketClient {

    public MyWebSocketClient(URI serverUri) {
        super(serverUri);
    }

    @Override
    public void onOpen(ServerHandshake serverHandshake) {
        System.out.println("连接成功!");
    }

    @Override
    public void onMessage(String s) {
        System.out.println("接收到服务端数据:"+s);
    }

    @Override
    public void onClose(int i, String s, boolean b) {
        System.out.println("关闭连接"+s);
    }

    @Override
    public void onError(Exception e) {
        System.out.println("发生异常"+e);
    }

}

再自定义一个类,创建一个static静态方法返回一个WebSocketClient对象

直接copy源码

这里就是创建了连接服务器的方法。

import com.xiaozhe.websocket.MyWebSocketClient;
import org.java_websocket.client.WebSocketClient;

import java.net.URI;
import java.net.URISyntaxException;

public class WebSocketDemo {

    public static WebSocketClient webSocketClient() {
        try {
            MyWebSocketClient webSocketClient = new MyWebSocketClient(new URI("ws://localhost:8080/websocketdemo"));
            webSocketClient.connect();
            return webSocketClient;
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }
}

编写一个Collections类,向服务端发送消息

我们可以使用浏览器url方式访问,也可以通过postman等测试工具来进行访问。
url : localhost:8080/sendfirst

import com.xiaozhe.bo.FirstClient;
import org.java_websocket.client.WebSocketClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebSocketController {

    WebSocketClient webSocketClient = WebSocketDemo.webSocketClient();

    @RequestMapping("sendfirst")
    public void sendfirst() {
        webSocketClient.send("百度搜索:程序员小哲");
    }

}

HTML 客户端

直接copy源码

简单的h5客户端代码,可以创建连接,断开连接,向服务端发送数据。

<!DOCTYPE HTML>
<html>
<head>
    <title>WebSocketDemo</title>
</head>

<body>
<button onclick="oppen()">创建链接</button>
<button onclick="closeWebSocket()">断开连接</button>
<hr>
<input id="text" type="text" />
<button onclick="send()">向服务器发送数据</button>
<div id="message"></div>
</body>
 
<script type="text/javascript">
    var websocket = null;
 
	//创建连接
    function oppen(){
		//判断当前浏览器是否支持WebSocket
		if('WebSocket' in window){
			//连接WebSocket节点
			websocket = new WebSocket("ws://localhost:8080/websocketdemo");
		}
		else{
			alert('当前浏览器不支持websocket');
		}
	 
		//连接发生错误的回调方法
		websocket.onerror = function(){
			setMessageInnerHTML("错误!");
		};
	 
		//连接成功建立的回调方法
		websocket.onopen = function(event){
			setMessageInnerHTML("连接成功!");
		}
	 
		//接收到消息的回调方法
		websocket.onmessage = function(event){
			setMessageInnerHTML(event.data);
		}
	 
		//连接关闭的回调方法
		websocket.onclose = function(){
			setMessageInnerHTML("连接关闭!");
		}
		//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
		window.onbeforeunload = function(){
			websocket.close();
		}
	 
		//将消息显示在网页上
		function setMessageInnerHTML(innerHTML){
			document.getElementById('message').innerHTML += innerHTML + '<br/>';
		}
    }
 
    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }
 
    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

进阶示例代码

之前的例子是实现单个客户端向服务端发送信息,但是如果服务端向指定的客户端发消息应该怎么做呢。那么请看下面的代码:
建议大家将代码复制到IDE中,便于查看,代码中有详细注释便于理解。

Spring Boot服务端

自动注册@ServerEndpoint注解

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

编写服务端代码

这里我们在主要的四大监听方法之外加了一些属性和方法。大家可以新建一个Spring boot项目来进行下面的项目。

import com.alibaba.fastjson.JSONObject;
import com.example.demo.zo.Xiao;
import com.example.demo.zo.Zhe;
import org.springframework.stereotype.Component;

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

@ServerEndpoint("/websocketdemoxiaozhe")
@Component
public class MyServer {

    //将所有客户端对象储存到Map集合中
    private static Map<String, MyServer> clients = new ConcurrentHashMap<String, MyServer>();
    //会话
    private Session session;
    //会话唯一标识,使用cid来确定唯一的
    private String cid;

    /**
     * 百度搜索:程序员小哲
     * 建立连接成功调用
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接成功!");
    }

    /**
     * 百度搜索:程序员小哲
     * 关闭连接时调用
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        System.out.println("关闭连接!");
    }

    /**
     * 百度搜索:程序员小哲
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(Session session,String message) {
        // message是一个json
        // 将message进行反序列化
        // 详见我的另一篇博客:https://blog.csdn.net/xiaozhezhe0470/article/details/110652012
        JSONObject jsonObject = JSONObject.parseObject(message);
        Zhe zhe = JSONObject.toJavaObject(jsonObject, Zhe.class);
        //由于我们是在创建之后才提交cid,所以我们需要在获取提交的信息的时候进行判断,查看是哪一次的请求
        if (zhe.getHi() != null){//第二次之后的请求
            System.out.println(zhe.getHi());
        }else {//第一次请求
            Xiao xiao = JSONObject.toJavaObject(jsonObject, Xiao.class);
            System.out.println(xiao);
            this.cid = xiao.getCid();
            this.session = session;
            clients.put(cid,this);
            try {
                //将信息返回到指定用户的页面中
                sendMessageTo("恭喜"+xiao.getWork()+xiao.getCname()+"注册成功!您的账号为:"+cid,cid);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 百度搜索:程序员小哲
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("连接异常:{}"+throwable);
    }

    /**
     * 百度搜索:程序员小哲
     * 向指定的客户端发送数据
     * @param message 推送的信息
     * @param cid 客户id
     */
    public void sendMessageTo(String message, String cid) throws IOException {
        MyServer myWebSocket = clients.get(cid);
        myWebSocket.session.getAsyncRemote().sendText(message);
    }

    /**
     * 百度搜索:程序员小哲
     * 给所有用户进行推送信息
     * @param message 推送的信息
     */
    public void sendMessageAll(String message) throws IOException {
        for (MyServer item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

}

向客户端推送请求

在这里我们新加了一个基础代码里面没有的类,就是给指定的用户推送消息。

import com.example.demo.config.MyServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class ServiceToClientDemo {

    @Autowired
    public MyServer myServer;

    /**
     * 给指定的用户推送信息
     * @param cid 用户注册后弹出的cid
     * @param message 想要推送给用户的信息
     */
    @GetMapping("/sendToClient")
    public void sendTo(String cid,String message) throws IOException {
        myServer.sendMessageTo(message,cid);
    }

    /**
     * 给所有用户推送信息
     * @param msg 想要推送给用户的信息
     */
    @GetMapping("/sendAllClient")
    public void sendAll(String msg) throws IOException {
        myServer.sendMessageAll(msg);
    }

}

所用实体类

引入依赖

使用实体类之前需要引入@Data的依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
第一次请求实体类
import lombok.Data;

@Data
public class Xiao {

    private String cid;
    private String work;
    private String cname;

}
第二次请求实体类
import lombok.Data;

@Data
public class Zhe {

    private String hi;

}

HTML客户端

与基础代码相比,多了一个登陆认证。这里需要注意的是,我们需要先创建连接,然后登陆认证,最后在向服务端发送数据,这里没有加验证,不按照顺序来会报错的。
再有一个就是我在两个文本框里面加了默认的JSON大家直接点击即可,方便大家操作。

<!DOCTYPE HTML>
<html>
<head>
    <title>Test My WebSocket</title>
</head>
 
<body>
<button onclick="oppen()">创建连接</button>
<button onclick="closeWebSocket()">断开连接</button>
<hr>
<input  id="text01" type="text" value="{ 	'cid': '713', 	'cname': '小哲', 	'work': '程序员' 	}"/>
<button onclick="first()">登陆认证</button>
<hr>
<input  id="text" type="text" value="{ 	'hi': '你好呀'  }" />
<button onclick="send()">向服务器发送数据</button>
<div id="message"></div>
</body>
 
<script type="text/javascript">
    var websocket = null;
 
	//创建连接
    function oppen(){
		//判断当前浏览器是否支持WebSocket
		if('WebSocket' in window){
			//var message01 = document.getElementById('text01').value;
			//连接WebSocket节点
			websocket = new WebSocket("ws://localhost:8080/websocketdemoxiaozhe");
		}
		else{
			alert('Not support websocket')
		}
	 
		//连接发生错误的回调方法
		websocket.onerror = function(){
			setMessageInnerHTML("error");
		};
	 
		//连接成功建立的回调方法
		websocket.onopen = function(event){
			setMessageInnerHTML("open");
		}
	 
		//接收到消息的回调方法
		websocket.onmessage = function(event){
			setMessageInnerHTML(event.data);
		}
	 
		//连接关闭的回调方法
		websocket.onclose = function(){
			setMessageInnerHTML("close");
		}
	 
		//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
		window.onbeforeunload = function(){
			websocket.close();
		}
	 
		//将消息显示在网页上
		function setMessageInnerHTML(innerHTML){
			document.getElementById('message').innerHTML += innerHTML + '<br/>';
		}
    }
 
    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }
	
	//登陆账号
	function first(){
		var message01 = document.getElementById('text01').value;
		websocket.send(message01);
	}
 
    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

超级进阶示例代码

大家有没有觉得每次创建连接在进行注册非常的麻烦,有没有一种办法可以直接在连接的时候就进行注册呢?那么请看下面的代码。

Spring Boot服务端代码

改动之处

一、 @ServerEndpoint("/websocketdemoxiaozhe01/{cid}")
在这里我们在后面加上了一个参数,就是我们的唯一标识cid。
二、 public void onOpen(@PathParam(“cid”) String cid, Session session) {…}
我们在onOpen方法里面多加了一个参数,注意第一个参数一定要用@PathParam修饰,不然项目跑不起来
然后就没有什么不一样了。直接上代码copy到开发工具上。

maven引入依赖

<!--WebSocket核心依赖包-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.java-websocket</groupId>
    <artifactId>Java-WebSocket</artifactId>
    <version>1.4.1</version>
    <scope>compile</scope>
</dependency>

自动注册@ServerEndpoint注解

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

开启服务端代码

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.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocketdemoxiaozhe01/{cid}")
@Component
public class MyDemoServer {

    //将当前对象储存到Map集合中
    private static Map<String, MyDemoServer> clients = new ConcurrentHashMap<String, MyDemoServer>();
    //会话
    private Session session;
    //会话唯一标识
    private String cid;

    /**
     * 百度搜索:程序员小哲
     * 建立连接成功调用
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("cid") String cid, Session session) {
        System.out.println("连接成功!");
        this.cid = cid;
        this.session = session;
        clients.put(cid,this);
        try {
            //将信息返回到指定用户的页面中
            sendMessageTo("恭喜注册成功!您的账号为:"+cid,cid);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 百度搜索:程序员小哲
     * 关闭连接时调用
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        System.out.println("关闭连接!");
    }

    /**
     * 百度搜索:程序员小哲
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(Session session,String message) {
        System.out.println(message);
    }

    /**
     * 百度搜索:程序员小哲
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("连接异常:{}"+throwable);
    }

    /**
     * 百度搜索:程序员小哲
     * 向指定的客户端发送数据
     * @param message 推送的信息
     * @param cid 客户id
     */
    public void sendMessageTo(String message, String cid) throws IOException {
        MyDemoServer myWebSocket = clients.get(cid);
        myWebSocket.session.getAsyncRemote().sendText(message);
    }

    /**
     * 百度搜索:程序员小哲
     * 给所有用户进行推送信息
     * @param message 推送的信息
     */
    public void sendMessageAll(String message) throws IOException {
        for (MyDemoServer item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

}

向客户端推送请求

示例url:http://localhost:8080/sendToClient01?cid=111&message=你好
示例url:http://localhost:8080/sendAllClient01?message=你们好

import com.xiaozhe.mywebsocketserver.server.MyDemoServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class ServiceToClientDemo {

    @Autowired
    MyDemoServer myDemoServer;

    /**
     * 给指定的用户推送信息
     * @param cid 用户注册后弹出的cid
     * @param message 想要推送给用户的信息
     */
    @GetMapping("/sendToClient01")
    public void sendTo(String cid,String message) throws IOException {
        myDemoServer.sendMessageTo(message,cid);
    }

    /**
     * 给所有用户推送信息
     * @param msg 想要推送给用户的信息
     */
    @GetMapping("/sendAllClient01")
    public void sendAll(String msg) throws IOException {
        myDemoServer.sendMessageAll(msg);
    }

}

H5 客户端代码

H5客户端唯一的区别就是在创建连接的时候将cid一起传到了后台。
websocket = new WebSocket(“ws://localhost:8080/websocketdemoxiaozhe01/” + message01);

<!DOCTYPE HTML>
<html>
<head>
    <title>Test My WebSocket</title>
</head>
 
<body>
websocketid
<input  id="text01" type="text" value="111"/>
<button onclick="oppen()">创建链接</button>
<hr>
<input  id="text" type="text" />
<button onclick="send()">向服务器发送数据</button>
<button onclick="closeWebSocket()">断开连接</button>
<div id="message"></div>
</body>
 
<script type="text/javascript">
    var websocket = null;

	//创建连接
    function oppen(){
		//判断当前浏览器是否支持WebSocket
		if('WebSocket' in window){
			var message01 = document.getElementById('text01').value;
			//连接WebSocket节点
			websocket = new WebSocket("ws://localhost:8080/websocketdemoxiaozhe01/" + message01);
		}
		else{
			alert('Not support websocket')
		}
	 
		//连接发生错误的回调方法
		websocket.onerror = function(){
			setMessageInnerHTML("error");
		};
	 
		//连接成功建立的回调方法
		websocket.onopen = function(event){
			setMessageInnerHTML("open");
		}
	 
		//接收到消息的回调方法
		websocket.onmessage = function(event){
			setMessageInnerHTML(event.data);
		}
	 
		//连接关闭的回调方法
		websocket.onclose = function(){
			setMessageInnerHTML("close");
		}
		//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
		window.onbeforeunload = function(){
			websocket.close();
		}
	 
		//将消息显示在网页上
		function setMessageInnerHTML(innerHTML){
			document.getElementById('message').innerHTML += innerHTML + '<br/>';
		}
    }
 
    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }
 
    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

彩蛋(获取源码)

  • 有问题可以扫码评论,我会一一进行回复。
  • 公众号以更名为:程序员小哲
  • 公众号内回复websocket领取本章源码

在这里插入图片描述

  • 65
    点赞
  • 231
    收藏
    觉得还不错? 一键收藏
  • 61
    评论
传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式 对于信息变化不频繁的Web应用来说造成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便,如带有即时通信、实时数据、订阅推送等功能的应 用。在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。 轮询是最原始的实现实时Web应用的解决方案。轮询技术要求客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动。明显地,这种方法会导致过多不必要的请求,浪费流量和服务器资源。 Comet技术又可以分为长轮询和流技术。长轮询改进了上述的轮询技术,减小了无用的请求。它会为某些数据设定过期时间,当数据过期后才会向服务端发送请求;这种机制适合数据的改动不是特别频繁的情况。流技术通常是指客户端使用一个隐藏的窗口与服务端建立一个HTTP长连接,服务端会不断更新连接状态以保持HTTP长连接存活;这样的话,服务端就可以通过这条长连接主动将数据发送给客户端;流技术在大并发环境下,可能会考验到服务端的性能。 这两种技术都是基于请求-应答模式,都不算是真正意义上的实时技术;它们的每一次请求、应答,都浪费了一定流量在相同的头部信息上,并且开发复杂度也较大。 伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力。WebSocket的工作流程是这 样的:浏览器通过JavaScript服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端服务端就可以通过 TCP连接传输数据。因为WebSocket连接本质上是TCP连接,不需要每次传输都带上重复的头部数据,所以它的数据传输量比轮询和Comet技术小 了很多。本文不详细地介绍WebSocket规范,主要介绍下WebSocketJava Web中的实现。 环境:jdk1.8.0_111,apache-tomcat-8.0.51
评论 61
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值