这功能不要问,问就是项目需求
直接上代码
import (
"demo/model"
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"net"
"net/http"
"os"
"strconv"
"sync"
"time"
)
var wsUpgrader = websocket.Upgrader{
// 允许所有CORS跨域请求
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// 开启成功的端口号
var DictPoirts []int
type DictHttp struct{}
// 接收到的数据!!
var Result map[string]*sync.Map
// 开几个go程
var TotalThread int = 5
func main() {
Result = make(map[string]*sync.Map,0)
DictPoirts = make([]int, 0)
count := 0
for i := 7780;; i++ {
handle := DictHttp{}
websocketServer := &http.Server{
Handler: handle,
ReadTimeout: time.Duration(1000000) * time.Millisecond,
WriteTimeout: time.Duration(1000000) * time.Millisecond,
}
listen, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(i))
if err != nil {
continue
}
count++
if count > TotalThread {
break
}
DictPoirts = append(DictPoirts, i)
go websocketServer.Serve(listen)
}
fmt.Println(DictPoirts)
for true {
}
}
// agent !!! - 写文件 - 接收
func (d DictHttp) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
// 应答客户端告知升级连接为websocket
wsSocket, err := wsUpgrader.Upgrade(resp, req, nil)
if err != nil {
return
}
fmt.Println("dict传输建立连接...")
for true {
_, countent, err := wsSocket.ReadMessage()
if err != nil {
fmt.Println("err=>", err)
wsSocket.Close()
break
}
if len(countent) == 0 {
continue
}
ret := &model.DictTransfer{}
err = proto.Unmarshal(countent, ret)
marshal, _ := json.Marshal(ret)
fmt.Println(string(marshal))
if err != nil {
fmt.Println("proto 解析错误")
return
}
// 解析完成,放入 sync.map 中
_, ok := Result[ret.Id]
if !ok {
Result[ret.Id] = &sync.Map{}
}
if ret.IsEnd == 1 {
go intoFile(ret.Id)
} else {
Result[ret.Id].Store(ret.PageNum, ret.Content)
}
}
}
// 写入文件
func intoFile(id string) {
file, _ := os.OpenFile("./3.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
defer file.Close()
fmt.Println("server 开始写文件")
time.Sleep(time.Second * 2)
// 文件发送完成
for i := 1; ; i++ {
num := int32(i)
load, ok := Result[id].LoadAndDelete(num)
if !ok {
break
}
// 写入文件
_, _ = file.Write(load.([]byte))
}
}
client
import (
"bufio"
"demo/model"
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"io"
"os"
"strconv"
"time"
)
// server - 读取文件 - 发送
var webSockets []*websocket.Conn
func main() {
dialer := websocket.Dialer{
HandshakeTimeout: 3 * time.Second,
}
for i := 7780; i < 7785; i++ {
ws, _, err := dialer.Dial("ws://127.0.0.1:"+strconv.Itoa(i), nil)
if err != nil {
fmt.Println(i, "--client => ", err)
return
}
webSockets = append(webSockets, ws)
}
fmt.Println("==>>开始读取文件")
// 读文件
open, _ := os.Open("./1.txt")
buf := make([]byte, 20)
reader := bufio.NewReader(open)
for i := 1; ; i++ {
tmp := i
isend := 2
n, err := reader.Read(buf)
if err != nil && err != io.EOF || n == 0 {
isend = 1
end := &model.DictTransfer{
PageNum: 0,
Id: open.Name(),
IsEnd: int32(isend),
}
endCon, _ := proto.Marshal(end)
_ = webSockets[tmp%5].WriteMessage(websocket.TextMessage, endCon)
break
}
ret := model.DictTransfer{
PageNum: int32(tmp),
Id: open.Name(),
Content: buf[:n],
IsEnd: int32(isend),
}
marshal, _ := proto.Marshal(&ret)
bytes, _ := json.Marshal(ret)
fmt.Println(string(bytes))
// 将读取到的数据发送
err = webSockets[tmp%5].WriteMessage(websocket.TextMessage, marshal)
if err != nil {
break
}
}
fmt.Println("==>>文件发送完成")
}
还有就是 proto的文件
记得protoc 一下
syntax = "proto3";
package model;
message DictTransfer {
int32 pageNum = 1; // 第几片
string id = 2; // 字典id
bytes content = 3; // 字典内容
int32 isEnd =4; // 是否是最后一片 1=是最后一片
}