当前位置:网站首页>Websocket transfer file
Websocket transfer file
2022-07-22 01:08:00 【fenglllle】
Preface
The previous chapter achieved websocket Transmitting text messages , In fact, the network transmission is binary 0 and 1, Therefore, files can also be transferred .
demo
Realization websocket Transfer files , Use the last example ,client
package com.feng.socket.client;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Scanner;
public class SocketClient {
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
Object condition = new Object();
WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://127.0.0.1:8083/websocket/server/10001")) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
System.out.println(serverHandshake.getHttpStatus() + " : " + serverHandshake.getHttpStatusMessage());
}
@Override
public void onMessage(String s) {
System.out.println("receive msg is " + s);
}
@Override
public void onMessage(ByteBuffer bytes) {
//To overwrite
byte mark = bytes.get(0);
if (mark == 2) {
synchronized (condition) {
condition.notify();
}
System.out.println("receive ack for file info");
} else if (mark == 6){
synchronized (condition) {
condition.notify();
}
System.out.println("receive ack for file end");
}
}
@Override
public void onClose(int i, String s, boolean b) {
System.out.println(s);
}
@Override
public void onError(Exception e) {
e.printStackTrace();
}
};
webSocketClient.connect();
while (!ReadyState.OPEN.equals(webSocketClient.getReadyState())) {
System.out.println("wait for connecting ...");
}
// webSocketClient.send("hello");
// Scanner scanner = new Scanner(System.in);
// while (scanner.hasNext()) {
// String line = scanner.next();
// webSocketClient.send(line);
// }
System.out.println("start websocket client...");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
if ("1".equals(scanner.next()))
sendFile(webSocketClient, condition);
}
}
public static void sendFile(WebSocketClient webSocketClient, Object condition){
new Thread(() -> {
try {
SeekableByteChannel byteChannel = Files.newByteChannel(Path.of("/Users/huahua/IdeaProjects/websocket-demo/websocket-demo/socket-client/src/main/resources/Thunder5.rar"),
new StandardOpenOption[]{StandardOpenOption.READ});
ByteBuffer byteBuffer = ByteBuffer.allocate(4*1024);
byteBuffer.put((byte)1);
String info = "{\"fileName\": \"Thunder5.rar\", \"fileSize\":"+byteChannel.size()+"}";
byteBuffer.put(info.getBytes(StandardCharsets.UTF_8));
byteBuffer.flip();
webSocketClient.send(byteBuffer);
byteBuffer.clear();
synchronized (condition) {
condition.wait();
}
byteBuffer.put((byte)3);
while (byteChannel.read(byteBuffer) > 0) {
byteBuffer.flip();
webSocketClient.send(byteBuffer);
byteBuffer.clear();
byteBuffer.put((byte)3);
}
byteBuffer.clear();
byteBuffer.put((byte)5);
byteBuffer.put("end".getBytes(StandardCharsets.UTF_8));
byteBuffer.flip();
webSocketClient.send(byteBuffer);
synchronized (condition) {
condition.wait();
}
byteChannel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
Server End use Tomcat Of websocket
package com.feng.socket.admin;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint("/websocket/server/{sessionId}")
public class SocketServer {
private static final Logger LOGGER = LoggerFactory.getLogger(SocketServer.class);
private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();
private String sessionId = "";
private SeekableByteChannel byteChannel;
@OnOpen
public void onOpen(Session session, @PathParam("sessionId") String sessionId) {
this.sessionId = sessionId;
sessionMap.put(sessionId, session);
LOGGER.info("new connect, sessionId is " + sessionId);
}
@OnClose
public void onClose() {
sessionMap.remove(sessionId);
LOGGER.info("close socket, the sessionId is " + sessionId);
}
@OnMessage
public void onMessage(String message, Session session) {
LOGGER.info("--------- receive message: " + message);
}
@OnMessage
public void onMessage(ByteBuffer byteBuffer, Session session) throws IOException {
if (byteBuffer.limit() == 0) {
return;
}
byte mark = byteBuffer.get(0);
if (mark == 1) {
byteBuffer.get();
String info = new String(byteBuffer.array(),
byteBuffer.position(),
byteBuffer.limit() - byteBuffer.position());
FileInfo fileInfo = new JsonMapper().readValue(info, FileInfo.class);
byteChannel = Files.newByteChannel(Path.of("/Users/huahua/"+fileInfo.getFileName()),
new StandardOpenOption[]{StandardOpenOption.CREATE, StandardOpenOption.WRITE});
//ack
ByteBuffer buffer = ByteBuffer.allocate(4096);
buffer.put((byte) 2);
buffer.put("receive fileinfo".getBytes(StandardCharsets.UTF_8));
buffer.flip();
session.getBasicRemote().sendBinary(buffer);
} else if (mark == 3) {
byteBuffer.get();
byteChannel.write(byteBuffer);
} else if (mark == 5) {
//ack
ByteBuffer buffer = ByteBuffer.allocate(4096);
buffer.clear();
buffer.put((byte) 6);
buffer.put("receive end".getBytes(StandardCharsets.UTF_8));
buffer.flip();
session.getBasicRemote().sendBinary(buffer);
byteChannel.close();
byteChannel = null;
}
}
@OnError
public void onError(Session session, Throwable error) {
LOGGER.error(error.getMessage(), error);
}
public static void sendMessage(Session session, String message) throws IOException {
session.getBasicRemote().sendText(message);
}
public static Session getSession(String sessionId){
return sessionMap.get(sessionId);
}
}
Realize the idea
Experience sharing
Actually, there are 2 A question
1. Tomcat Of websocket The default maximum can only be sent 8K The data of
The root cause is
org.apache.tomcat.websocket.WsSession
// Buffers
static final int DEFAULT_BUFFER_SIZE = Integer.getInteger(
"org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE", 8 * 1024)
.intValue();
private volatile int maxBinaryMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;
private volatile int maxTextMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE;
Through system variables , perhaps JVM -D Parameters can be set
org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE
2. json Formatting problems , If the attribute of the object has byte[] Array
fastjson and Jackson It's using Base64 The way of dealing with gson Is the true byte[] Array storage , Just the string is included .
summary
actually websocket yes tcp Duplex protocol on , There is no problem transferring files , Just need to define the application layer protocol . If you use Tomcat Of websocket transmission , Pay attention to the transmission content size . and HTTP 2.0 and HTTP 3.0 Not available websocket, In especial http 3.0 UDP agreement .
边栏推荐
- 类模板重载输出运算符报错
- &lt;a&gt;標簽跳轉到Servelet頁面並實現參數的傳遞
- dom——防抖与节流
- 数字化打开第二增长曲线,华为总结运营商云转型三大场景
- 06. Introduction, installation and simple use of octave
- Based on tensorflow2.0+ use Bert to obtain Chinese word and sentence vectors and conduct similarity analysis
- visual studio引用外部庫的注意事項
- 【HCIP持续更新】DHCP安全威胁
- Low code tool revolution on the cusp of the storm
- Web自动化处理“滑动验证码”
猜你喜欢
Centos7在线安装MySQL
2022 Blue Bridge Cup provincial match group B supplementary questions [decimal to decimal], [shunzi date], [question brushing statistics], [pruning shrubs]
OpenShift Security (17) - 将 OpenShift Compliance Operator 的合规扫描集成到 RHACS
剑指offer_知识迁移能力
websocket 传输文件
Digitalization opens the second growth curve. Huawei summarizes three scenarios of cloud transformation of operators
Lens calibration board
【HCIP持续更新】DHCP安全威胁
Cloud native and low code platforms make agile enterprises
HCIA NAT experiment report 7.14
随机推荐
解析惠及中小学校的Steam教育
What platform can accommodate knowledge base, indicator base and rule base at the same time?
[hcip continuous update] DHCP security threat
【RM_EE_Note】1 GM6020收发&简单的PID调试
从0到1 拿下C语言—程序结构及使用示例
镜头标定板秩事
The Sandbox 联手 Agoria,共同打造 Agoriaverse
ROS multi coordinate transformation
CUDA文件中无法打开源文件<stdio.h>
Uniapp wechat applet user authorization to obtain user information
if-else:if判断语句和执行语句之间相差1个时钟周期吗?并行执行吗?有优先级吗?
HCIA NAT experiment report 7.14
Considérations relatives à la référence de la bibliothèque externe par Visual Studio
探寻机器人创客教育中的趣味
牛客刷题 01——KiKi去重整数并排序(C语言)
Precautions for visual studio to reference external libraries
温度信号测量K型热电偶信号采集器rs485/232远程IO转换模块
Verilog: bitwise, logical
解读符合新时代主流的创客教育模式
Business innovation driven by metadata to build new competitive advantages of enterprises