應(yīng)用環(huán)境:
B/S架構(gòu)
需求描述:
1、判斷U盤接入
2、掃描U盤指定文件,將滿足條件的文件發(fā)送給服務(wù)器
解決思路:
1、因為bs架構(gòu),無法獲取本機資源,計劃在U盤所在服務(wù)器部署websocket服務(wù)
2、websocket服務(wù)掃描u盤,拿到指定文件,使用session.getBasicRemote().sendBinary(data)分批發(fā)送二進制流到客戶端
3、web端的收到二進制流后將分批數(shù)據(jù)存到數(shù)組
4、數(shù)據(jù)接收全部完畢后,通過formData將數(shù)據(jù)提交到服務(wù)端進行保存,
5、當時想到websocket直接將文件傳給后端服務(wù)器,但只想websocket服務(wù)只是作與web端的數(shù)據(jù)傳輸,具體文件還是由web端與后端服務(wù)器進行交互。
定時任務(wù),檢查U盤插入找到指定文件,并將文件的二進制流發(fā)給客戶端
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sims.tools.webSocket.WebSocketServer;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@EnableScheduling//開啟定時任務(wù)
@Component
public class CheckTask {
private static boolean findFile = false;
private static boolean hasUsb = false;
private static String usbPath = "";
private static List<String> roots = new ArrayList<>();
@Scheduled(cron = "0/5 * * * * ? ")
public void cron() {
try {
System.out.println("定時任務(wù)是否執(zhí)行:" + !findFile+"--根目錄文件夾數(shù)"+roots.size());
if(findFile){
//文件已經(jīng)導(dǎo)入了
System.out.println("文件已經(jīng)導(dǎo)入了,如果想再導(dǎo)入,撥掉u盤再插入");
List<String> newRoots = new ArrayList<>();
FileSystems.getDefault().getRootDirectories().forEach(root -> {
newRoots.add(root.toString());
});
if(newRoots.size()<roots.size()){
//新目錄少于現(xiàn)有目錄,更新
findFile = false;
roots = newRoots;
usbPath = "";
System.out.println("U盤被拔出");
}
} else {
//文件未導(dǎo)入,繼續(xù)檢測
System.out.println("文件未導(dǎo)入,繼續(xù)檢測");
if (roots.size() == 0) {
// 獲取系統(tǒng)中的所有文件系統(tǒng)
FileSystems.getDefault().getRootDirectories().forEach(root -> {
roots.add(root.toString());
});
} else {
List<String> newRoots = new ArrayList<>();
// 獲取系統(tǒng)中的所有文件系統(tǒng)
FileSystems.getDefault().getRootDirectories().forEach(root -> {
if ((roots.indexOf(root.toString()) < 0) || (root.toString().equals(usbPath))) {
System.out.println("U盤已插入,路徑為:" + root);
hasUsb = true;
usbPath = root.toString();
try {
Files.walk(root).forEach(path -> {
if (Files.isRegularFile(path)) {
if (path.toString().endsWith("erc")) {
System.out.println("文件:" + path);
JSONObject obj1 = new JSONObject();
obj1.put("msgType","sendFileBegin");
WebSocketServer.sendInfo(JSON.toJSONString(obj1), "user0");
WebSocketServer.sendFile(path.toString(),"user0");
JSONObject obj2 = new JSONObject();
obj2.put("msgType","sendFileEnd");
obj2.put("fileName",path.toString());
WebSocketServer.sendInfo(JSON.toJSONString(obj2), "user0");
findFile = true;
}
}
});
} catch (IOException e) {
System.out.println("io錯誤:" + e.getMessage());
findFile = false;
}
}
newRoots.add(root.toString());
});
if(newRoots.size()< roots.size()){
//U盤被拔出
System.out.println("U盤被拔出");
usbPath = "";
findFile = false;
}
roots = newRoots;
}
}
} catch (Exception e) {
System.out.println("報錯了" + e.getMessage());
findFile = false;
}
}
}
Websocket服務(wù)代碼
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;
/**
* websocket的處理類。
* 作用相當于HTTP請求
* 中的controller
*/
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocketServer {
/**靜態(tài)變量,用來記錄當前在線連接數(shù)。應(yīng)該把它設(shè)計成線程安全的。*/
private static int onlineCount = 0;
/**concurrent包的線程安全Set,用來存放每個客戶端對應(yīng)的WebSocket對象。*/
private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
/**與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)*/
private Session session;
/**接收userId*/
private String userId = "";
public String getUserId(){
return this.userId;
}
/**
* 連接建立成
* 功調(diào)用的方法
*/
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
this.session = session;
this.userId=userId;
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
//加入set中
webSocketMap.put(userId,this);
}else{
//加入set中
webSocketMap.put(userId,this);
//在線數(shù)加1
addOnlineCount();
}
System.out.println("用戶連接:"+userId+",當前在線人數(shù)為:" + getOnlineCount());
try {
InetAddress ip = InetAddress.getLocalHost();
System.out.println("Current IP address : " + ip.getHostAddress());
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
byte[] mac = network.getHardwareAddress();
System.out.print("Current MAC address : ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
System.out.println(sb);
JSONObject object = new JSONObject();
object.put("ip",ip.getHostAddress());
object.put("mac",sb);
JSONObject obj = new JSONObject();
obj.put("msgType","ipAndMac");
obj.put("result",object);
sendInfo(JSON.toJSONString(obj),this.userId);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e){
e.printStackTrace();
}
}
/**
* 連接關(guān)閉
* 調(diào)用的方法
*/
@OnClose
public void onClose() {
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
//從set中刪除
subOnlineCount();
}
System.out.println("用戶退出:"+userId+",當前在線人數(shù)為:" + getOnlineCount());
}
/**
* 收到客戶端消
* 息后調(diào)用的方法
* @param message
* 客戶端發(fā)送過來的消息
**/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("用戶消息:"+userId+",報文:"+message);
//可以群發(fā)消息
//消息保存到數(shù)據(jù)庫、redis
if(message!=null && message.length()>0){
try {
//解析發(fā)送的報文
JSONObject jsonObject = JSON.parseObject(message);
//追加發(fā)送人(防止串改)
jsonObject.put("fromUserId",this.userId);
String toUserId=jsonObject.getString("toUserId");
//傳送給對應(yīng)toUserId用戶的websocket
if(toUserId!=null && toUserId.length()>0 &&webSocketMap.containsKey(toUserId)){
webSocketMap.get(toUserId).sendMessage(message);
}else{
//否則不在這個服務(wù)器上,發(fā)送到mysql或者redis
System.out.println("請求的userId:"+toUserId+"不在該服務(wù)器上");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
/**
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("用戶錯誤:"+this.userId+",原因:"+error.getMessage());
error.printStackTrace();
}
/**
* 實現(xiàn)服務(wù)
* 器主動推送
*/
public void sendMessage(String message) {
try {
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendByteBuffer(ByteBuffer data) {
System.out.print(data);
try {
session.getBasicRemote().sendBinary(data);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*發(fā)送自定
*義消息
**/
public static void sendInfo(String message, String userId) {
System.out.println("發(fā)送消息到:"+userId+",報文:"+message);
if(userId!=null && userId.length()>0 && webSocketMap.containsKey(userId)){
webSocketMap.get(userId).sendMessage(message);
}else{
System.out.println("用戶"+userId+",不在線!");
}
}
public static void sendFile(String path, String userId) {
if(userId!=null && userId.length()>0 && webSocketMap.containsKey(userId)){
try {
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer, 0, bytesRead);
webSocketMap.get(userId).sendByteBuffer(byteBuffer);
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}else{
System.out.println("用戶"+userId+",不在線!");
}
}
/**
*發(fā)送自定
*義消息
**/
public void sendInfoToAll(String message) {
System.out.println("發(fā)送報文:"+message);
sendMessage(message);
}
/**
* 獲得此時的
* 在線人數(shù)
* @return
*/
public static synchronized int getOnlineCount() {
return onlineCount;
}
/**
* 在線人
* 數(shù)加1
*/
public static synchronized void addOnlineCount() {
WebSocketServer.onlineCount++;
}
/**
* 在線人
* 數(shù)減1
*/
public static synchronized void subOnlineCount() {
WebSocketServer.onlineCount--;
}
}
Vue前端代碼
websocketOnmessage: function (e){
let data = e.data
let that = this;
console.log("rec====", data);
if (this.isBlob(data)) {
console.log("recdata===", data)
this.recData.push(data);
} else {
let record = JSON.parse(data)
if (record.msgType == "ipAndMac") {
if(!sessionStorage.getItem('ipAndMac')){
let result = record.result;
loginLog(result).then(res=>{
console.log('res',res)
if(res.data.success){
sessionStorage.setItem('ipAndMac',result)
}
})
}
} else if (record.msgType == "sendFileBegin") {
//開始接收服務(wù)端發(fā)送過來的文件數(shù)據(jù)
this.recData = [];
} else if (record.msgType == "sendFileEnd") {
//文件數(shù)據(jù)的接收完畢,合并數(shù)據(jù)并上傳到業(yè)務(wù)服務(wù)器
if (this.recData.length == 0) return;
this.$showMsgBox({
caption:"詢問",
msg: '檢查到待導(dǎo)入文件' + record.fileName + ',是否導(dǎo)入?',
callback:(data) => {
if (data == "yes") {
var formData = new FormData()
formData.append('file', new Blob(this.recData))
formData.append('fileName', record.fileName);
let url = config.configData.api_url + "/business/biz/importAllByPath";
utils.httpFile(url,formData).then((res) => {
if (res.data.success == true) {
that.$showImport({tableData:res.data.data})
} else {
this.$showToast({msg: res.data.message});
return;
}
})
}
}
})
}
}
},
特別注意這個寫法不要搞錯,formData.append('file', new Blob(this.recData)),否則后端接受不到正確的格式數(shù)據(jù)。文章來源:http://www.zghlxwxcb.cn/news/detail-791473.html
服務(wù)端接收前端上傳數(shù)據(jù)代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-791473.html
@RequestMapping(value = "/importAllByPath", method = RequestMethod.POST)
public Result<?> importAllByPath(HttpServletRequest request, HttpServletResponse response) {
String fileName = request.getParameter("fileName");
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 獲取上傳文件對象
try {
String uuid = StrUtils.getTimeNo("sims_data_");
String path = uploadpath + File.separator + "temp" + File.separator + uuid + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
String sFile = new File(path).getAbsolutePath() + File.separator + uuid + ".erc";
try (FileOutputStream outputStream = new FileOutputStream(sFile)) {
byte[] bytes = file.getBytes();
outputStream.write(bytes);
} catch (Exception e) {
return Result.error("文件導(dǎo)入失敗:" + e.getMessage());
}
return Result.ok(result);
} catch (Exception e) {
return Result.error("文件導(dǎo)入失敗:" + e.getMessage());
}
}
return Result.ok("導(dǎo)入失敗");
}
到了這里,關(guān)于Java Websocket發(fā)送文件給Vue客戶端接收并上傳,實現(xiàn)檢測U盤插入并將指定文件上傳到服務(wù)器功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!