WebSocket介绍

  WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

  WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

  在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

  现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

  HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

  

  

  浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

  当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

  以下 API 用于创建 WebSocket 对象。

  var Socket = new WebSocket(url, [protocol] );

  以上代码中的第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。

WebSocket 客户端页面实现

 <!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>WebSocket测试</title>
</head>
<body style="text-align: center;">
<h2>WebSocket测试</h2>
<div>
<input type="text" id="txt"/>
<button onclick="sendWebSocket()">发送</button><br>
<button onclick="checkWebSocket()">测试WebSocket</button>
<button onclick="connectWebSocket()">连接WebSocket</button>
<button onclick="closeWebSocket()">关闭WebSocket</button><br>
<hr>
<div id="message"></div>
</div>
</body>
<script type="text/javascript"> var websocket = null; function checkWebSocket(){
if ("WebSocket" in window) {
// alert("您的浏览器支持 WebSocket!");
setMessageInnerHTML("您的浏览器支持 WebSocket!");
}
else {
// 浏览器不支持 WebSocket
// alert("您的浏览器不支持 WebSocket!");
setMessageInnerHTML("您的浏览器不支持 WebSocket!");
}
} // 连接 WebSocket
function connectWebSocket(){
// 打开一个 web socket
websocket = new WebSocket("ws://localhost:8080/test-websocket/websocket");
websocket.onopen = function() {
// Web Socket 已连接上,使用 send() 方法发送数据
setMessageInnerHTML("WebSocket 已连接...");
};
websocket.onmessage = function(evt) {
var received_msg = evt.data;
setMessageInnerHTML("收到消息:" + received_msg);
};
websocket.onclose = function()
{
setMessageInnerHTML("WebSocket 已关闭...");
};
} // 向WebSocket服务端发送消息
function sendWebSocket(){
if (websocket){
if (websocket.readyState == websocket.OPEN) {
var message = document.getElementById('txt').value;
websocket.send(message);
} else {
setMessageInnerHTML("WebSocket 未连接...");
}
}else {
setMessageInnerHTML("WebSocket 未创建...");
}
} // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
} // 关闭WebSocket连接
function closeWebSocket() {
websocket.close();
} // 将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
</script>
</html>

WebSocket 服务端Java实现

  java 实现websocket的两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket

  一、Tomcat的WebSocket实现

    1、新建一个Maven Web工程,参考:【Maven】Eclipse 使用Maven创建Java Web项目,添加websocket依赖如下:

<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>

    2、编辑一个WebSocket服务端类,MyWebSocket.class

 package com.test.websocket;

 import java.io.IOException;

 import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/websocket")
public class MyWebSocket { private Session session; /**
* 连接建立后触发的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
WebSocketMapUtil.put(session.getId(), this);
System.out.println("-------- onOpen: 当前在线人数 " + WebSocketMapUtil.getOnlineCount() + ",连接人 " + session.getId() + " --------");
} /**
* 连接关闭后触发的方法
*/
@OnClose
public void onClose() {
// 从map中删除
WebSocketMapUtil.remove(session.getId());
System.out.println("-------- onClose: 当前在线人数 " + WebSocketMapUtil.getOnlineCount() + ",关闭人 " + session.getId() + " --------");
} /**
* 接收到客户端消息时触发的方法
*/
@OnMessage
public void onMessage(String message, Session session) throws Exception {
// 获取服务端到客户端的通道
MyWebSocket myWebSocket = WebSocketMapUtil.get(session.getId());
System.out.println("收到来自 " + session.getId() + " 的消息:" + message); // 返回消息给Web Socket客户端(浏览器)
myWebSocket.sendMessageAll("服务端已收到消息:" + message);
} /**
* 发生错误时触发的方法
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("-------- onError: 当前在线人数 " + WebSocketMapUtil.getOnlineCount() + ",连接发生错误 " + session.getId() + "-"+ error.getMessage() + " --------");
// error.printStackTrace();
} /**
* 给单个客户端发送消息
* @param message
* @param sessionId
* @throws IOException
*/
public void sendMessageSingle(String message, String sessionId) throws IOException { // session.getBasicRemote().sendText(message); 同步消息
// session.getAsyncRemote().sendText(message); 异步消息 MyWebSocket myWebSocket = WebSocketMapUtil.get(sessionId);
if(myWebSocket != null) {
myWebSocket.session.getBasicRemote().sendText(message);
}
} /**
* 给所有客户端发送消息
* @param message
* @throws IOException
*/
public void sendMessageAll(String message) throws IOException {
for (MyWebSocket item : WebSocketMapUtil.getValues() ) {
item.session.getAsyncRemote().sendText(message);
System.out.println(item.session.getId());
System.out.println(item.session.isSecure());
System.out.println(item.session.isOpen());
}
} }

    3、编辑一个WebSocket 工具类,WebSocketMapUtil.class

 package com.test.websocket;

 import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; public class WebSocketMapUtil { public static ConcurrentMap<String, MyWebSocket> webSocketMap = new ConcurrentHashMap<>(); public static void put(String key, MyWebSocket myWebSocket) {
webSocketMap.put(key, myWebSocket);
} public static MyWebSocket get(String key) {
return webSocketMap.get(key);
} public static void remove(String key) {
webSocketMap.remove(key);
} public static Collection<MyWebSocket> getValues() {
return webSocketMap.values();
} public static int getOnlineCount() {
return webSocketMap.size();
}
}

    4、将项目发布到Tomcat中,使用浏览器访问界面(http://127.0.0.1:8080/test-websocket/static/websocket.html)

      界面输出如下:

      

      服务端输出如下:

      

    

  二、Spring的WebSocket实现

    1、新建一个Maven Web工程,参考:【Maven】Eclipse 使用Maven创建SpringMVC Web项目,添加Spring-Websocket依赖如下:

 <!--Spring WebSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
 <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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>test-websocket</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>test-websocket Maven Webapp</name>
<url>http://maven.apache.org</url> <!-- 定义maven变量 -->
<properties>
<!-- spring -->
<spring.version>5.0.0.RELEASE</spring.version> <!-- log -->
<commons-logging.version>1.1.3</commons-logging.version> <!-- Servlet -->
<servlet.version>3.0.1</servlet.version>
<jsp-api.version>2.2</jsp-api.version> <!-- jstl -->
<jstl.version>1.2</jstl.version>
<standard.version>1.1.2</standard.version> <!-- test -->
<junit.version>3.8.1</junit.version> <!-- jdk -->
<jdk.version>1.7</jdk.version>
<maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
</properties> <dependencies>
<!--Spring WebSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.3.13.RELEASE</version>
</dependency> <dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.4.0</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> <!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency> <!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency> <dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>${standard.version}</version>
</dependency> <!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<type>jar</type>
<scope>compile</scope>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>0.9.30</version>
<type>jar</type>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.30</version>
<type>jar</type>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>0.9.30</version>
</dependency> </dependencies> <build>
<plugins>
<!-- define the project compile level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
<finalName>test-websocket</finalName>
</build> </project>

pom.xml

    2、新建一个websocket消息处理类,MyWebSocketHandler.java

 package com.test.socket.handler;

 import java.io.IOException;

 import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler; public class MyWebSocketHandler extends AbstractWebSocketHandler { @Override
public void afterConnectionEstablished(WebSocketSession session) {
WebSocketHandlerUtil.put(session.getId(), session);
System.out.println("-------- onOpen: 当前在线人数 " + WebSocketHandlerUtil.getOnlineCount() + ",连接人 "
+ session.getId() + " --------");
} @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
// 从map中删除
WebSocketHandlerUtil.remove(session.getId());
System.out.println("-------- onClose: 当前在线人数 " + WebSocketHandlerUtil.getOnlineCount() + ",关闭人 " + session.getId() + " --------");
} /**
* 在UI在用js调用websocket.send()时候,会调用该方法
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// super.handleTextMessage(session, message);
// 获取服务端到客户端的通道
System.out.println("收到来自 " + session.getId() + " 的消息:" + message.getPayload()); // 返回消息给Web Socket客户端(浏览器)
sendMessageAll("服务端已收到消息:" + message);
} /**
* 发生错误时触发的方法
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
System.out.println("-------- onError: 当前在线人数 " + WebSocketHandlerUtil.getOnlineCount() + ",连接发生错误 " + session.getId() + "-"+ exception.getMessage() + " --------");
} /**
* 给单个客户端发送消息
* @param message
* @param sessionId
* @throws IOException
*/
public void sendMessageSingle(String message, String sessionId) throws IOException { WebSocketSession session = WebSocketHandlerUtil.get(sessionId);
if(session != null) {
session.sendMessage(new TextMessage(message));
}
} /**
* 给所有客户端发送消息
* @param message
* @throws IOException
*/
public void sendMessageAll(String message) throws IOException {
for (WebSocketSession session : WebSocketHandlerUtil.getValues() ) { session.sendMessage(new TextMessage(message));
}
} }

    3、WebSocketHandlerUtil.java,工具类

 package com.test.socket.handler;

 import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import org.springframework.web.socket.WebSocketSession; public class WebSocketHandlerUtil { public static ConcurrentMap<String, WebSocketSession> webSocketMap = new ConcurrentHashMap<>(); public static void put(String key, WebSocketSession webSocketSession) {
webSocketMap.put(key, webSocketSession);
} public static WebSocketSession get(String key) {
return webSocketMap.get(key);
} public static void remove(String key) {
webSocketMap.remove(key);
} public static Collection<WebSocketSession> getValues() {
return webSocketMap.values();
} public static int getOnlineCount() {
return webSocketMap.size();
}
}

    4、新建一个拦截器,WebSocketHandshakeInterceptor.java ,可以处理请求到达websocket前的逻辑

 package com.test.socket.handler;

 import java.util.Map;

 import javax.servlet.http.HttpServletRequest;

 import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor; public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { @Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
// 请求 进入WebSocket处理器,处理相关逻辑
return true;
} @Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception exception) {
// TODO Auto-generated method stub } }

    5、WebSocket配置类,WebSocketConfig.java,需要让SpringMvc扫描到这个类

 package com.test.socket.handler;

 import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistration;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { /**
*
* @param registry 该对象可以调用addHandler()来注册信息处理器。
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
WebSocketHandlerRegistration handler = registry.addHandler(myWebSocketHandler(), "/myWebSocket");
handler.addInterceptors(webSocketHandshakeInterceptor()); // 声明拦截器
handler.setAllowedOrigins("*"); // 声明允许访问的主机列表
} @Bean
public MyWebSocketHandler myWebSocketHandler() {
return new MyWebSocketHandler();
} @Bean
public WebSocketHandshakeInterceptor webSocketHandshakeInterceptor() {
return new WebSocketHandshakeInterceptor();
} }

    6、spring-mvc.xml,文件如下:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <!-- 自动扫描的包名 -->
<context:component-scan base-package="com.test.socket.handler" /> <!-- 默认的注解映射的支持 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean
class="org.springframework.http.converter.ResourceHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven> <!-- 视图解释类,定义跳转的文件的前后缀 -->
<!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"
/> <property name="prefix" value="/views/" /> <property name="suffix" value=".jsp"
/> <property name="requestContextAttribute" value="rc" /> </bean> -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/view/" />
<property name="suffix" value=".jsp" />
</bean> <!-- 拦截器 -->
<!-- <mvc:interceptors> <bean class="com.fpx.ce.foundation.preference.PreferenceChangeInterceptor"
/> <mvc:interceptor> <mvc:mapping path="/page/home"/> <bean class="com.fpx.ce.foundation.user.UserInterceptor"
/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/service/**" />
<bean class="com.fpx.ce.foundation.log.LogHandlerInterceptor" /> </mvc:interceptor>
<mvc:interceptor> <mvc:mapping path="/test/**" /> <mvc:mapping path="/service/**"
/> <bean class="com.lemon.finder.web.SharedRenderVariableInterceptor" />
</mvc:interceptor> </mvc:interceptors> --> <!-- 对静态资源文件的访问 方案一 (二选一) -->
<mvc:default-servlet-handler /> <!-- 对静态资源文件的访问 方案二 (二选一) -->
<!-- <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>
<mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>
<mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/> --> <!-- <bean id="myWebSocket" class="com.test.socket.handler.MyWebSocketHandler" /> <websocket:handlers>
<websocket:mapping handler="myWebSocket" path="/myWebSocket"/>
</websocket:handlers> --> </beans>

    7、将项目发布到Tomcat中,使用浏览器访问界面(http://127.0.0.1:8080/test-websocket/static/websocket.html),将界面中WebSocket连接地址改为:ws://localhost:8080/test-websocket/myWebSocket

      

WebSocket 客户端Java实现

  1、新建一个Java Maven项目,引入依赖

 <dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.4.0</version>
</dependency>

  2、编辑Java WebSocket类

 package com.test.websocket;

 import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator; import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake; public class MyWebSocketClient extends WebSocketClient { public MyWebSocketClient(URI serverUri) {
super(serverUri);
} @Override
public void onOpen(ServerHandshake handshakedata) {
// TODO Auto-generated method stub
System.out.println("------ MyWebSocket onOpen ------");
for (Iterator<String> it = handshakedata.iterateHttpFields(); it.hasNext();) {
String key = it.next();
System.out.println(key + ":" + handshakedata.getFieldValue(key));
}
} @Override
public void onClose(int code, String reason, boolean remote) {
// TODO Auto-generated method stub
System.out.println("------ MyWebSocket onClose ------");
} @Override
public void onError(Exception ex) {
// TODO Auto-generated method stub
System.out.println("------ MyWebSocket onError ------");
} @Override
public void onMessage(String message) {
// TODO Auto-generated method stub
System.out.println("-------- 接收到服务端数据: " + message + "--------");
} public static void main(String[] arg0) throws URISyntaxException, InterruptedException {
MyWebSocketClient myClient = new MyWebSocketClient(new URI("ws://localhost:8080/test-websocket/myWebSocket"));
// 连接
myClient.connect(); while (!myClient.getReadyState().equals(ReadyState.OPEN)) {
System.out.println("MyWebSocketClient 连接中 ...");
} // 往websocket服务端发送数据
myClient.send("MyWebSocketClient Message"); // 调用此方法保持住连接
myClient.sendPing(); Thread.sleep(3000);
myClient.close();
}
}

  3、测试,运行main方法

    

  

【WebSocket】WebSocket快速入门的更多相关文章

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

    ebSocket.之.基础入门-断开连接处理 在<WebSocket.之.基础入门-后端响应消息>的代码基础之上,继续更新代码.代码只改动了:TestSocket.java 和 index ...

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

    WebSocket.之.基础入门-后端响应消息 在<WebSocket.之.基础入门-前端发送消息>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 inde ...

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

    WebSocket.之.基础入门-前端发送消息 在<WebSocket.之.基础入门-建立连接>的代码基础之上,进行添加代码.代码只改动了:TestSocket.java 和 index. ...

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

    WebSocket.之.基础入门-建立连接 1. 使用开发工具(STS.Eclipse等)创建web项目.如下图所示,啥东西都没有.一个新的web项目. 2. 创建java类.index.jsp页面. ...

  5. 快速入门系列--MVC--07与HTML5移动开发的结合

    现在移动互联网的盛行,跨平台并兼容不同设备的HTML5越来越盛行,很多公司都在将自己过去的非HTML5网站应用渐进式的转化为HTML5应用,使得一套代码可以兼容不同的物理终端设备和浏览器,极大的提高了 ...

  6. spring boot入门教程——Spring Boot快速入门指南

    Spring Boot已成为当今最流行的微服务开发框架,本文是如何使用Spring Boot快速开始Web微服务开发的指南,我们将使创建一个可运行的包含内嵌Web容器(默认使用的是Tomcat)的可运 ...

  7. WEEX快速入门

    WEEX快速入门 WEEX 是阿里推送的一款基于Node.js,轻量级的移动端跨平台动态性技术解决方案,用于构建原生的速度的跨平台APP. 1. 搭建WEEX环境 1.1 首先下载安装Node.js, ...

  8. Spring Boot WebFlux 快速入门实践

    02:WebFlux 快速入门实践 Spring Boot 2.0 spring.io 官网有句醒目的话是: BUILD ANYTHING WITH SPRING BOOT Spring Boot ( ...

  9. Spring Boot 2 快速教程:WebFlux 快速入门(二)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 02:WebFlux 快速入门实践 文章工程: JDK 1.8 ...

随机推荐

  1. 新建本地用户连接vsftp出现530 Login incorrect

    新建的用户的方式 [root@centos2 /var/ftp]# useradd -s /sbin/nologin user1 出错原因: /etc/pam.d/vsftp文件作了限制 [root@ ...

  2. Spring Cloud Ribbon负载均衡(快速搭建)

    Spring Cloud Ribbon 是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现.通过 Spring Cloud 的封装, 可以让我们轻松地将面向服务的 ...

  3. solr和ElasticSearch(ES)的区别?

    Solr2004年诞生 ElasticSearch 2010年诞生 ES更新 ElasticSearch简介: ElasticSearch是一个实时的分布式的搜索引擎和分析引擎.它可以帮助你用前所未有 ...

  4. dt系统中tag如何使用like与%来进行模糊查询

    在destoon中,如果一个品牌的详细显示页,如果要显示与品牌相关的供应的话,可以通过查询标题中带有品牌关键字的这一条件来进行查询,但是经过测试发现不能正确解析, 然后查看文件的源文件,发现 {tag ...

  5. node爬虫爬取中文时乱码问题 | nodejs gb2312、GBK中文乱码解决方法

    iconv需要依赖native库,这样一来,在一些不支持native模块安装的虚拟主机和windows平台上,我们还是无法安心处理GBK编码. 老外写了一个通过纯Javascript转换编码的模块 i ...

  6. java代码操作word模板并生成PDF

    这个博客自己现在没时间写,等后面有时间了,自己再写. 这中需求是在实际的项目开发中是会经常遇到的. 下面我们先从简单入手一步一步开始. 1.首先,使用word创建一个6行两列的表格. 点击插入-6行2 ...

  7. 常见的transformation算子

    RDD:RDD分区数,若从HDFS创建RDD,RDD的分区就是和文件块一一对应,若是集合并行化形式创建,RDD分区数可以指定,一般默认值是CPU的核数. task:task数量就是和分区数量对应. 一 ...

  8. 2019-2020-1 20199302《Linux内核原理与分析》第七周作业

    第六章 进程的描述和进程的创建 (一)进程的描述 1.OS的三大管理功能:(1)进程管理(进程)(2)内存管理(虚拟内存)(3)文件系统(文件) 2.进程的描述:进程控制块PCB 3.在Linux内核 ...

  9. spring-cloud(一)

    1.SpringCloud概述和搭建Eureka服务注册中心 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注 ...

  10. rust cargo 一些方便的三方cargo 子命令扩展

    内容来自cargo 的github wiki,记录下,方便使用 可选的列表 cargo-audit - Audit Cargo.lock for crates with security vulner ...