1、Socket 类
socket可以使一个应用从网络中读取和写入数据,不同计算机上的两个应用可以通过连接发送和接受字节流。当发送消息时,你需要知道对方的ip和端口。在java中,socket指的是java.net.Socket类。
在java.net.Socket中,可以看到socket有多种构造函数
以public Socket(String host, int port)为例,host为远程机器名称或ip地址,port为端口号。若连接本地的Server,其端口号为8080,可以写成如下格式
new Socket(“localhost”, 8080);
一旦成功创建一个Socket类的实例,可以用它来发送和接收字节流,发送时调用getOutputStream方法获取一个java.io.OutputStream对象,接收远程对象发送来的信息可以调用getInputStream方法来返回一个java.io.InputStream对象。
serversocket
现在,要实现一个服务器应用,需要不同的做法。服务器需随时待命,因为不知道客户端什么时候会发来请求,此时,我们需要使用ServerSocket,对应的是java.net.ServerSocket类。
ServerSocket与Socket不同,ServerSocket是等待客户端的请求,一旦获得一个连接请求,就创建一个Socket示例来与客户端进行通信。
回忆一下Socket,它是一种用于实现网络通信的编程接口。Socket可以在应用层和下面所有层之间进行通信,它提供了一种相对简单的方式来进行网络通信。在Socket编程中,服务器端需要创建一个ServerSocket对象来监听指定端口,并通过accept方法接受客户端的连接请求。而客户端则需要创建一个Socket对象,并通过指定的端口连接到服务器。接着,服务器端和客户端都可以使用Socket对象的getInputStream方法和getOutputStream方法来进行数据的读写操作。
WebSocket
之间有什么不同?可以回忆一下socket并学习一下websocket吗?
回答: Serversocket和Websocket是两种不同的通信协议。Serversocket是Java中用于实现服务器端的Socket编程的类,它用于监听指定端口并接受客户端的连接请求。通过Serversocket,服务器可以创建一个Socket对象与客户端进行通信。[2]而Websocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许服务器主动向客户端推送数据,而不需要客户端发起请求。Websocket使用HTTP协议进行握手,然后在建立连接后,通过长连接实现实时通信。
关于Socket的回忆,Socket是一种在应用层和下面所有层之间的通信接口,它可以帮助我们以相对简单的方式进行网络通信。Socket可以用于实现客户端和服务器之间的通信,通过Socket可以建立连接、发送和接收数据。在Socket编程中,服务器端需要创建一个ServerSocket对象来监听指定端口并接受客户端的连接请求,而客户端则需要创建一个Socket对象来连接服务器。通过Socket对象的输入流和输出流,可以进行数据的读写操作。
总结起来,Serversocket是用于实现服务器端的Socket编程的类,用于监听指定端口并接受客户端的连接请求,而Websocket是一种在Web浏览器和服务器之间进行全双工通信的协议。Socket是一种通信接口,用于实现客户端和服务器之间的通信。
再来看看webSocket,spring集成实现,类似springMVC
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
.实现WebSocketHandler,用于处理信息
package com.fp.controller.websocket;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
public class MyWebSocketHandler implements WebSocketHandler{
private List<WebSocketSession> sessions = new ArrayList<WebSocketSession>();
//建立
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("afterConnectionEstablished");
sessions.add(session);
}
//发送消息
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
System.out.println("handleMessage");
for(WebSocketSession se : sessions){
se.sendMessage(message);
}
System.out.println(message);
session.sendMessage(message);
}
//异常
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("handleTransportError");
}
//关闭
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("afterConnectionClosed");
}
@Override
public boolean supportsPartialMessages() {
System.out.println("supportsPartialMessages");
return false;
}
}
实现拦截器HttpSessionHandshakeInterceptor
package com.fp.controller.websocket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpMessage;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
public class MyHttpSessionHandshakeInterceptor extends HttpSessionHandshakeInterceptor{
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
// 解决The extension [x-webkit-deflate-frame] is not supported问题
if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions",
"permessage-deflate");
}
System.out.println("Before Handshake");
/* String domain = request.getHeaders().getOrigin();
System.out.println(domain);
HttpHeaders headers = response.getHeaders();
headers.setAccessControlAllowOrigin(domain);
List<HttpMethod> list = new ArrayList<HttpMethod>();
list.add(HttpMethod.GET);
list.add(HttpMethod.POST);
list.add(HttpMethod.DELETE);
list.add(HttpMethod.POST);
list.add(HttpMethod.OPTIONS);
headers.setAccessControlAllowMethods(list);
headers.setAccessControlAllowCredentials(true);*/
/*headers
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Control-Expose-Headers");
response.setHeader("Access-Control-Expose-Headers", "Content-Type"); */
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out.println("After Handshake");
/*String domain = request.getHeaders().getOrigin();
HttpHeaders headers = response.getHeaders();
headers.setAccessControlAllowOrigin(domain);
List<HttpMethod> list = new ArrayList<HttpMethod>();
list.add(HttpMethod.GET);
list.add(HttpMethod.POST);
list.add(HttpMethod.DELETE);
list.add(HttpMethod.POST);
list.add(HttpMethod.OPTIONS);
headers.setAccessControlAllowMethods(list);
headers.setAccessControlAllowCredentials(true);*/
ex.printStackTrace();
super.afterHandshake(request, response, wsHandler, ex);
}
}
spring配置
<bean id="websocket" class="com.fp.controller.websocket.MyWebSocketHandler"/>
<websocket:handlers allowed-origins="*">
<!-- path表示对应的连接 -->
<websocket:mapping path="/websocket" handler="websocket"/>
<!-- 这个class是连接的流程控制方法,这个重写HttpSessionHandshakeInterceptor的方法-->
<websocket:handshake-interceptors>
<bean class="com.fp.controller.websocket.MyHttpSessionHandshakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>
前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--<script src="http://libs.baidu.com/jquery/1.10.0/jquery.min.js"></script>-->
<script src="js/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script>
<title></title>
</head>
<body>
<input type="" name="" id="sendtext" value="" />
<input type="button" id="send" value="发送" />
<div id="return">
</div>
</body>
<script type="text/javascript">
var url = 'ws://localhost:8080/ws/websocket';
//var url = 'ws://echo.websocket.org/';
var socket = new WebSocket(url);
socket.onopen = function( ){
console.log("open ");
$("#return").text("open");
}
socket.onclose = function( ){
console.log("close ");
$("#return").text("close");
}
socket.onmessage = function(e){
console.log("onmessage ");
console.log(e.data);
$("#return").text(e.data);
}
$("#send").click(function(){
var text = $("#sendtext").val();
socket.send(text);
});
</script>
</html>
websocket原理
是一个应用层协议,说的是,目前浏览器实现的一套通信协议,用来解决之前HTTP,请求响应模型不合适的场合。
首先HTTP有1.1和1.0之说,也就是所谓的keep-alive,把多个HTTP请求合并为一个,但是Websocket其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解
1) HTTP的生命周期通过Request来界定,也就是一个Request 一个Response,那么 在 HTTP1.0 中 ,这次HTTP请求就结束了。
在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。
但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是 被动 的,不能主动发起。
首先Websocket是基于HTTP协议的,或者说 借用 了HTTP的协议来完成一部分握手。
在握手阶段是一样的
首先我们来看个典型的Websocket握手
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com