Java WebSocket 实践1 - 基于javax

Java WebSocket 实践1-基于javax

webSocket 的定义

  • WebSocket 是一种全双工的通信协议,基于Http之上,可以实现服务端和客户端之间建立一个长连接 ,实现服务端主动向客户端推送消息,客户端也可以主动向服务端发送消息的功能。
  • 常见的使用场景就是:客户端需要高频率的向服务端发起同一个Http请求,类似于轮询的方式,这种解决方案的缺陷主要有两个方面:
  1. 消息不及时
  2. 浪费大量的带宽和服务器资源。
    这种情况下,websocket就派上用场了。

webSocket 中的概念

webSocket 和单纯的Http请求最大不同,就是webSocket 是双向的通信,http是单向的,所以websocket中会存在一些基本的生命周期的概念。作为一个协议,各种不同的编程语言都有不同的实现形式,但是都是围绕这些中心的生命周期来的。

  • connect : 客户端同服务端发起连接。 连接需要用到一个URL :
  • URL : webSocket 的URL 以ws作为开头,中间和http一样是host和端口port,后边加上服务端定义的请i去路径。不同的是这个URL 只是用来建立连接的,建立连接之后,就是双方互相通信了。就像是两个人打电话,拨通电话时候用到的电话号码就是这儿的这个URL ,电话接通了,两个人就可以说话了。webSoket URl 示意图

webSocket 在java 中的实现方式。

基于javax的服务端实现:
  1. 导入依赖包
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
		</dependency>
	</dependencies>

这里直接使用了spring-boot-starter-websocket ,这个starter中已经包含了javax的依赖,所以不需要重复引入javax-websoket 的相关jar包了。


  1. 配置EndPoint ,实现服务端websocket 的主要业务。
package com.example.demo.service;

import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@Service
// 定义了服务端webSoket的访问地址
@ServerEndpoint("/test/websocket")
public class MyEndPoint {

    private Session session;

    @OnOpen
    public void myOnOpen (Session session) {
        this.session = session;
        System.out.println("客户端已经链接");
    }

    @OnMessage
    public String myOnMessage (String txt) throws IOException {
        System.out.println(txt);
        return "服务端收到并返回";
    }

    @OnClose
    public void myOnClose (CloseReason reason) {
        System.out.println ("Closing a WebSocketConfig due to "+reason.getReasonPhrase());
    }

    @OnError
    public void onError(Throwable throwable){
        System.out.println("连接已经关闭");
    }


}

注解说明:
@ServerEndpoint("/test/websocket")用来声明这是一个服务端的websoket 。
@Open方法名随便定义,需要一个Session 对象作为参数。 可以在这里定义一些连接后的逻辑
@Message处理收到websocekt 消息后的业务逻辑,return 要返回的消息即可。当然也可以用open时候获取到的那个Session,手动发送。具体方法是:session.getBasicRemote().sendText();
@OnClose: 处理连接后的事务
@OnError: 处理连接失败的情况


  1. 配置webSoket : 这里向Spring中注册一个ServerEndpointExporter 对象。
package com.example.demo.service;

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

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

到此,一个服务端的demo就ok 了。


基于javax的客户端实现
  • 客户端实现,处理和服务端建立连接后的业务逻辑。
package com.example.demo.service;

import org.springframework.stereotype.Service;

import javax.websocket.*;
import java.io.IOException;

@Service
@ClientEndpoint
public class MyClientEndPoint {


    private Session session;

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        System.out.println ("WebSocketConfig opened: "+session.getId());
        System.out.println("服务端链接成功");
        try {
            this.sendMessage();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnMessage
    public String onMessage(String txt) throws IOException, InterruptedException {
        System.out.println(txt);
        Thread.sleep(1000);
        return "客户端收到";
    }

    @OnClose
    public void onClose(CloseReason reason) {
        System.out.println ("Closing a WebSocketConfig due to "+reason.getReasonPhrase());
    }

    @OnError
    public void onError(Throwable throwable){
        System.out.println("连接已经关闭");
    }

    public void sendMessage() throws IOException {
        this.session.getBasicRemote().sendText("客户端发送");
    }


}


  • 配置类代码和服务端一致。

  • 启动类代码:
package com.example.demo;

import com.example.demo.service.MyClientEndPoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.WebSocketContainer;
import java.io.IOException;
import java.net.URI;

/**
 * @author duanqichao
 */
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) throws IOException, DeploymentException {
		SpringApplication.run(DemoApplication.class, args);
		// 这里需要使用一个WebSoketContainer 对象来和服务端的连接
		WebSocketContainer container = ContainerProvider.getWebSocketContainer();
		String uri = "ws://localhost:8080/test/websocket";
		// 连接服务端的地址和处理类信息
		container.connectToServer(MyClientEndPoint.class, URI.create(uri));
	}
}

至此,一个webSoket的小demo 就可以运行了。

webSocket 如何测试:

Http 接口通常可以使用postman这类工具来模拟请求,类似的,也有一些websocket 的工具可以用来做webSocket 的客户端,推荐两个:

  1. 一个网址:http://websoket-test.com
  2. chrome 浏览器插件 : 去chrome 市场去看一下,直接搜索websoket client ,随便选一个都可以。websocket 插件结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值