prepare for test

This commit is contained in:
link 2022-03-16 15:41:14 +08:00
parent 892cd99eb3
commit 9796c5aad7
17 changed files with 412 additions and 269 deletions

View file

@ -9,6 +9,7 @@ DateTimeFormat = 2006-01-02 15:04:05
TimeFormat = 15:04:05
DateFormat = 2006-01-02
ProjectPath = /casaOS/server
RootPath = /casaOS
[server]
@ -44,3 +45,6 @@ ConfigStr =
WidgetList =
Analyse =
[file]
ShareDir =
DownloadDir = /DATA

12
main.go
View file

@ -6,6 +6,7 @@ import (
"net/http"
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/cache"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
@ -32,9 +33,14 @@ func init() {
//gredis.GetRedisConn(config.RedisInfo),
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
service.Cache = cache.Init()
//go service.UDPConnect([]string{})
go service.SocketConnect()
//go service.UDPService()
go service.UDPService()
go service.UDPConnect([]string{})
service.Summary = make(map[string]model.FileSummaryModel)
service.UDPAddressMap = make(map[string]string)
//go service.SocketConnect()
route.InitFunction()
}

View file

@ -40,7 +40,6 @@ type FileDetailModel struct {
type FileSummaryModel struct {
Hash string `json:"hash"` //Verify file
Name string `json:"name"`
Path string `json:"path"`
BlockSize int `json:"block_size"`
Length int `json:"length"`
Size int64 `json:"size"`

View file

@ -39,6 +39,7 @@ type APPModel struct {
TimeFormat string
DateFormat string
ProjectPath string
RootPath string
}
//公共返回模型
@ -76,3 +77,8 @@ type SystemConfig struct {
type CasaOSGlobalVariables struct {
AppChange bool
}
type FileSetting struct {
ShareDir []string `json:"share_dir" delim:"|"`
DownloadDir string `json:"download_dir"`
}

View file

@ -35,6 +35,8 @@ var SystemConfigInfo = &model.SystemConfig{}
var CasaOSGlobalVariables = &model.CasaOSGlobalVariables{}
var FileSettingInfo = &model.FileSetting{}
var Cfg *ini.File
//初始化设置,获取系统的部分信息。
@ -58,6 +60,7 @@ func InitSetup(config string) {
mapTo("redis", RedisInfo)
mapTo("server", ServerInfo)
mapTo("system", SystemConfigInfo)
mapTo("file", FileSettingInfo)
SystemConfigInfo.ConfigPath = configDir
// AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd()

View file

@ -60,9 +60,9 @@ func ComparisonHash(data []byte, hash string) bool {
//get prefix byte length
func PrefixLength(byteLength int) []byte {
lengthByte := []byte{'0', '0', '0', '0'}
lengthByte := []byte{'0', '0', '0', '0', '0', '0'}
bSize := strconv.Itoa(byteLength)
cha := 4 - len(bSize)
cha := 6 - len(bSize)
for i := len(bSize); i > 0; i-- {
lengthByte[cha+i-1] = bSize[i-1]
}

View file

@ -25,7 +25,7 @@ func InitFunction() {
Update2_3()
CheckSerialDiskMount()
CheckToken2_9()
CheckToken2_11()
}
@ -236,11 +236,24 @@ func CheckSerialDiskMount() {
func Update2_3() {
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
}
func CheckToken2_9() {
func CheckToken2_11() {
if len(config.ServerInfo.Token) == 0 {
token := uuid.NewV4().String
config.ServerInfo.Token = token()
config.Cfg.Section("server").Key("Token").SetValue(token())
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
if len(config.AppInfo.RootPath) == 0 {
config.Cfg.Section("app").Key("RootPath").SetValue("/casaOS")
config.AppInfo.RootPath = "/casaOS"
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
// str := []string{}
// str = append(str, "ddd")
// str = append(str, "aaa")
// ddd := strings.Join(str, "|")
// config.Cfg.Section("file").Key("ShareDir").SetValue(ddd)
// config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}

View file

@ -290,13 +290,14 @@ func InitRouter() *gin.Engine {
v1PersonGroup := v1Group.Group("/persion")
v1PersonGroup.Use()
{
// v1PersonGroup.GET("/test", v1.PersonTest)
v1PersonGroup.GET("/test", v1.PersonTest)
v1PersonGroup.GET("/users", v1.GetPersionFriend) //用户列表
v1PersonGroup.POST("/user", v1.PostAddPersionFriend) //添加用户
v1PersonGroup.GET("/directory", v1.GetPersionDirectory) //文件列表
//v1PersonGroup.GET("/download", v1.GetPersionFile) //下载文件
v1PersonGroup.GET("/file", v1.GetPersionFile) //下载文件
v1PersonGroup.PUT("/edit/:token", v1.PutPersionNick) //修改好友
v1PersonGroup.GET("/list", v1.GetPersionDownloadList) //下载列表(需要考虑试试下载速度)
v1PersonGroup.DELETE("/file/id", v1.DeletePersionDownloadFile)
// v1PersonGroup.PUT("/state/:id", v1.PutPersionCancelDownload) //修改下载状态(开始暂停删除)
}

View file

@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
@ -13,75 +12,26 @@ import (
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
uuid "github.com/satori/go.uuid"
)
func PersonTest(c *gin.Context) {
token := c.Query("token")
//service.MyService.Person().GetPersionInfo("fb2333a1-72b2-4cb4-9e31-61ccaffa55b9")
m := model.ConnectState{}
m.CreatedAt = time.Now()
m.From = config.ServerInfo.Token
m.To = "fb2333a1-72b2-4cb4-9e31-61ccaffa55b9"
m.Type = ""
m.UUId = uuid.NewV4().String()
//service.MyService.Person().Handshake(m)
msg := model.MessageModel{}
msg.Type = "connection"
msg.Data = "fb2333a1-72b2-4cb4-9e31-61ccaffa55b9"
msg.Type = "hello"
msg.Data = ""
msg.From = config.ServerInfo.Token
msg.UUId = "1234567890"
b, _ := json.Marshal(msg)
err := service.WebSocketConn.WriteMessage(websocket.TextMessage, b)
msg.To = token
msg.UUId = uuid.NewV4().String()
dd, err := service.Dial("", msg)
if err == nil {
return
fmt.Println(err)
}
}
//get other persion file
func GetPersionFile(c *gin.Context) {
path := c.Query("path")
persion := c.Query("persion")
if len(path) == 0 && len(persion) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
//任务标识
uuid := uuid.NewV4().String()
//1.通知对方需要下载
service.MyService.Person().GetFileDetail(uuid, path, persion)
//2.添加数据库
task := model2.PersionDownloadDBModel{}
task.UUID = uuid
task.Name = ""
task.Length = 0
task.Size = 0
task.State = types.DOWNLOADAWAIT
task.TempPath = ""
task.Type = 0
service.MyService.Person().AddDownloadTask(task)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
func GetPersionDownloadList(c *gin.Context) {
path := c.Query("path")
persion := c.Query("persion")
if len(path) == 0 && len(persion) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
//任务标识
uuid := uuid.NewV4().String()
//1.通知对方需要下载
service.MyService.Person().GetFileDetail(uuid, path, persion)
fmt.Println(dd)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
@ -92,7 +42,87 @@ func GetPersionDownloadList(c *gin.Context) {
// @Param token formData int true "Opponent token"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /persion/edit [put]
// @Router /persion/file/{id} [delete]
func GetPersionFile(c *gin.Context) {
path := c.Query("path")
token := c.Query("token")
if len(path) == 0 && len(token) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
//任务标识
uuid := uuid.NewV4().String()
//2.添加数据库
task := model2.PersionDownloadDBModel{}
task.UUID = uuid
task.Name = ""
task.Length = 0
task.Size = 0
task.State = types.DOWNLOADAWAIT
task.Type = 0
service.MyService.Download().AddDownloadTask(task)
m := model.MessageModel{}
m.Data = path
m.From = config.ServerInfo.Token
m.To = token
m.Type = "file_data"
m.UUId = uuid
_, err := service.Dial("192.168.2.224:9902", m)
if err != nil {
fmt.Println(err)
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
// @Summary delete download file records
// @Produce application/json
// @Accept application/json
// @Tags persion
// @Param token formData int true "Opponent token"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /persion/file/{id} [delete]
func DeletePersionDownloadFile(c *gin.Context) {
id := c.Param("id")
if len(id) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
service.MyService.Download().DelDownload(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
// @Summary get file download list
// @Produce application/json
// @Accept application/json
// @Tags persion
// @Param state query int true "wait:1,loading:1,pause:2,finish:3,error:4" Enums(0,1,2,4)
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /persion/list [get]
func GetPersionDownloadList(c *gin.Context) {
state := c.DefaultQuery("state", "")
list := service.MyService.Download().GetDownloadListByState(state)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
}
// @Summary add friend
// @Produce application/json
// @Accept application/json
// @Tags persion
// @Param token formData int true "Opponent token"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /persion/edit/{token} [put]
func PutPersionNick(c *gin.Context) {
token := c.Param("token")
nick := c.PostForm("nick")
@ -107,7 +137,7 @@ func PutPersionNick(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
// @Summary add friend
// @Summary get friends list
// @Produce application/json
// @Accept application/json
// @Tags persion
@ -134,15 +164,16 @@ func PostAddPersionFriend(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
//step:远程验证token是否存在
msg := model.MessageModel{}
msg.Type = types.PERSONADDFRIEND
msg.To = token
msg.Type = "connection"
msg.Data = token
msg.From = config.ServerInfo.Token
msg.To = token
msg.UUId = uuid.NewV4().String()
b, _ := json.Marshal(msg)
err := service.WebSocketConn.WriteMessage(websocket.TextMessage, b)
_, err := service.Dial("", msg)
fmt.Println(err)
friend := model2.FriendModel{}
@ -151,10 +182,18 @@ func PostAddPersionFriend(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
// @Summary get directory list
// @Produce application/json
// @Accept application/json
// @Tags persion
// @Param token query int true "Opponent token"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
// @Router /persion/directory [get]
func GetPersionDirectory(c *gin.Context) {
path := c.Query("path")
persion := c.Query("persion")
if len(path) == 0 && len(persion) == 0 {
token := c.Query("token")
if len(path) == 0 && len(token) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
@ -163,10 +202,10 @@ func GetPersionDirectory(c *gin.Context) {
m := model.MessageModel{}
m.Data = path
m.From = config.ServerInfo.Token
m.To = persion
m.To = token
m.Type = "directory"
m.UUId = uuid
result, err := service.Dial("192.168.2.225:9902", m)
result, err := service.Dial(service.UDPAddressMap[token], m)
if err != nil {
fmt.Println(err)
}

52
service/download.go Normal file
View file

@ -0,0 +1,52 @@
package service
import (
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"gorm.io/gorm"
)
type DownloadService interface {
AddDownloadTask(m model2.PersionDownloadDBModel) //添加下载任务
EditDownloadState(m model2.PersionDownloadDBModel) //只修改状态
SaveDownload(m model2.PersionDownloadDBModel)
DelDownload(uuid string)
GetDownloadById(uuid string) model2.PersionDownloadDBModel
GetDownloadListByState(state string) []model2.PersionDownloadDBModel
}
type downloadService struct {
db *gorm.DB
}
func (d *downloadService) AddDownloadTask(m model2.PersionDownloadDBModel) {
d.db.Create(&m)
}
func (d *downloadService) EditDownloadState(m model2.PersionDownloadDBModel) {
d.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State)
}
func (d *downloadService) DelDownload(uuid string) {
var m model2.PersionDownloadDBModel
d.db.Where("uuid = ?", uuid).Delete(&m)
}
func (d *downloadService) GetDownloadById(uuid string) model2.PersionDownloadDBModel {
var m model2.PersionDownloadDBModel
d.db.Model(m).Where("uuid = ?", uuid).First(&m)
return m
}
func (d *downloadService) GetDownloadListByState(state string) (list []model2.PersionDownloadDBModel) {
if len(state) == 0 {
d.db.Find(&list)
} else {
d.db.Where("state = ?", state).Find(&list)
}
return
}
func (d *downloadService) SaveDownload(m model2.PersionDownloadDBModel) {
d.db.Save(&m)
}
func NewDownloadService(db *gorm.DB) DownloadService {
return &downloadService{db: db}
}

View file

@ -1,6 +1,8 @@
package service
import (
"reflect"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"gorm.io/gorm"
)
@ -12,6 +14,7 @@ type FriendService interface {
GetFriendById(m model2.FriendModel) model2.FriendModel
GetFriendList() (list []model2.FriendModel)
UpdateAddFriendType(m model2.FriendModel)
UpdateOrCreate(m model2.FriendModel)
}
type friendService struct {
@ -38,6 +41,17 @@ func (p *friendService) GetFriendList() (list []model2.FriendModel) {
return list
}
func (p *friendService) UpdateOrCreate(m model2.FriendModel) {
friend := model2.FriendModel{}
p.db.Where("token = ?", m.Token).First(&friend)
if reflect.DeepEqual(friend, model2.FriendModel{}) {
p.db.Create(&m)
} else {
p.db.Model(&m).Updates(m)
}
}
func (p *friendService) UpdateAddFriendType(m model2.FriendModel) {
p.db.Model(&m).Updates(m)
}

View file

@ -5,20 +5,14 @@ type PersionDownloadDBModel struct {
State int `json:"state"` //
Type int `json:"type"` //defult 1
Name string `json:"name"` //file name
TempPath string `json:"temp_path"` //temp path
Size int64 `json:"size"` //file size
Section string `json:"section"`
BlockSize int `json:"block_size"`
Length int `json:"length"` //slice length
Hash string `json:"hash"`
CreatedAt string `gorm:"<-:create;autoCreateTime" json:"created_at"`
UpdatedAt string `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at"`
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"`
}
func (p *PersionDownloadDBModel) TableName() string {
return "o_persion_download"
}
type PersionFileSectionModel struct {
Index int `json:"index"`
Hash string `json:"hash"`
}

View file

@ -2,8 +2,8 @@ package model
type FriendModel struct {
State int `json:"state"` //备用
CreatedAt string `gorm:"<-:create;autoCreateTime" json:"created_at"`
UpdatedAt string `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at"`
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"`
NickName string `json:"nick_name"` //custom name
Avatar string `json:"avatar"` //头像
Name string `json:"name"`

View file

@ -40,14 +40,6 @@ type PersonService interface {
ReplyGetFileDetail(m model.MessageModel)
ReceiveFileData(m model.MessageModel)
ReceiveGetFileDetail(m model.MessageModel)
//------------ database
AddDownloadTask(m model2.PersionDownloadDBModel) //添加下载任务
EditDownloadState(m model2.PersionDownloadDBModel) //只修改状态
EditDownloading(m model2.PersionDownloadDBModel, section model2.PersionFileSectionModel)
SaveDownloadState(m model2.PersionDownloadDBModel)
DelDownload(uuid string)
GetDownloadById(uuid string) model2.PersionDownloadDBModel
}
type personService struct {
@ -81,7 +73,7 @@ func (p *personService) Handshake(m model.ConnectState) {
//1先进行udp打通成功
srcAddr := &net.UDPAddr{
IP: net.IPv4zero, Port: 9901} //注意端口必须固定
IP: net.IPv4zero, Port: 9904} //注意端口必须固定
dstAddr := &net.UDPAddr{
IP: net.ParseIP(config.ServerInfo.Handshake), Port: 9527}
//DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6"如果laddr不是nil将使用它作为本地地址否则自动选择一个本地地址。
@ -101,7 +93,6 @@ func (p *personService) Handshake(m model.ConnectState) {
if err != nil {
fmt.Printf("error during read: %s", err)
}
conn.Close()
toPersion := model.PersionModel{}
err = json.Unmarshal(data[:n], &toPersion)
if err != nil {
@ -116,33 +107,6 @@ func (p *personService) Handshake(m model.ConnectState) {
}
func (p *personService) AddDownloadTask(m model2.PersionDownloadDBModel) {
p.db.Create(&m)
}
func (p *personService) EditDownloadState(m model2.PersionDownloadDBModel) {
p.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State)
}
func (p *personService) EditDownloading(m model2.PersionDownloadDBModel, section model2.PersionFileSectionModel) {
b, _ := json.Marshal(section)
m.Section = string(b)
p.db.Model(&m).Where("uuid = ?", m.UUID).Update("section", m.Section)
}
func (p *personService) DelDownload(uuid string) {
var m model2.PersionDownloadDBModel
p.db.Where("uuid = ?", uuid).Delete(&m)
}
func (p *personService) GetDownloadById(uuid string) model2.PersionDownloadDBModel {
var m model2.PersionDownloadDBModel
p.db.Model(m).Where("uuid = ?", uuid).First(&m)
return m
}
func (p *personService) SaveDownloadState(m model2.PersionDownloadDBModel) {
p.db.Save(&m)
}
var ipAddress chan string
type sysConn struct {
@ -152,104 +116,11 @@ type sysConn struct {
}
func UDPConnect(ips []string) {
quicConfig := &quic.Config{
ConnectionIDLength: 12,
HandshakeIdleTimeout: time.Second * 8,
MaxIdleTimeout: time.Second * 45,
MaxIncomingStreams: 32,
MaxIncomingUniStreams: -1,
KeepAlive: true,
}
fmt.Println(quicConfig)
//PersonUDPMap = make(map[string]*net.UDPAddr)
ipAddress = make(chan string)
srcAddr := &net.UDPAddr{
IP: net.IPv4zero, Port: 9901}
fmt.Println(srcAddr)
//UDPconn, err := net.ListenUDP("udp", srcAddr)
// sysconn := &sysConn{
// conn: UDPconn,
// header: "",
// auth: nil,
// }
// if err != nil {
// fmt.Println(err)
// }
// liste, err := quic.Listen(UDPconn, generateTLSConfig(), nil)
// if err != nil {
// fmt.Println(err)
// }
// ssss, err := liste.Accept(context.Background())
// if err != nil {
// fmt.Println(err)
// }
// st, err := ssss.AcceptStream(context.Background())
// if err != nil {
// fmt.Println(err)
// }
// st.Write([]byte("ssss"))
qlister, err := quic.ListenAddr("0.0.0.0:9901", generateTLSConfig(), nil)
//qlister, err := quic.Listen(UDPconn, nil, nil)
if err != nil {
fmt.Println("quic错误", qlister)
}
//session, e := qlister.Accept()
sess, err := qlister.Accept(context.Background())
sess.SendMessage([]byte("aaaa"))
stream, err := sess.AcceptStream(context.Background())
stream.Write([]byte("bbb"))
//quic.Dial()
if err != nil {
fmt.Println("quic错误", qlister)
}
//m := model.ConnectState{}
if err != nil {
fmt.Println("监听错误", err.Error())
}
for _, v := range ips {
dstAddr := &net.UDPAddr{
IP: net.ParseIP(v), Port: 9901}
//MyService.Person().Handshake(m)
fmt.Println(v, "开始监听")
//quic.Dial()
go AsyncUDPConnect(dstAddr)
}
for {
data := make([]byte, 1024)
n, add, err := UDPconn.ReadFromUDP(data)
fmt.Println(add)
if err != nil {
log.Printf("error during read:%s\n", err)
} else {
fmt.Println("收到数据:", string(data[:n]))
msg := model.MessageModel{}
err := json.Unmarshal(data[:n], &msg)
if err != nil {
log.Printf("转义错误:%s\n", err)
}
//todo:检查数据库是否为合法请求
if msg.Type == "hi" {
//add ip
//PersonUDPMap[msg.From] = add
} else if msg.Type == "browse" {
//获取目录结构
} else if msg.Type == "file_detail" {
MyService.Person().ReplyGetFileDetail(msg)
} else if msg.Type == "file_detail_reply" {
MyService.Person().ReceiveGetFileDetail(msg)
} else if msg.Type == "file_data_reply" {
MyService.Person().ReceiveFileData(msg)
} else {
fmt.Println("未知事件")
}
}
}
}
// Setup a bare-bones TLS config for the server
@ -327,7 +198,6 @@ func (p *personService) Download(m model.MessageModel) {
}
summary := model.FileSummaryModel{}
summary.Hash = file.GetHashByPath(fDetail.Name())
summary.Path = m.Data.(string)
summary.BlockSize, summary.Length = file.GetBlockInfo(fDetail.Size())
msg := model.MessageModel{}
@ -349,7 +219,8 @@ func (p *personService) Download(m model.MessageModel) {
//receive file data
func (p *personService) ReceiveFileData(m model.MessageModel) {
task := p.GetDownloadById(m.UUId)
//task := p.GetDownloadById(m.UUId)
task := model2.PersionDownloadDBModel{}
//需要重置参数
tempPath := "/oasis/download/" + task.UUID
@ -391,7 +262,7 @@ func (p *personService) ReceiveFileData(m model.MessageModel) {
if h := file.GetHashByPath(filePath); h == task.Hash {
//最终文件比对成功
task.State = types.DOWNLOADFINISH
p.EditDownloadState(task)
//p.EditDownloadState(task)
//remove temp path
file.RMDir(tempPath)
}
@ -417,7 +288,6 @@ func (p *personService) ReplyGetFileDetail(m model.MessageModel) {
summary.Name = f.Name()
summary.Size = f.Size()
summary.Hash = file.GetHashByPath(path)
summary.Path = path
summary.BlockSize, summary.Length = file.GetBlockInfo(f.Size())
msg := model.MessageModel{}
@ -477,24 +347,24 @@ func (p *personService) SendFileData(m model.MessageModel, blockSize int, length
// 文件摘要返回
func (p *personService) ReceiveGetFileDetail(m model.MessageModel) {
task := p.GetDownloadById("")
bss, _ := json.Marshal(m.Data)
summary := model.FileSummaryModel{}
err := json.Unmarshal(bss, &summary)
if err != nil {
fmt.Println(err)
}
task.Hash = summary.Hash
task.Length = summary.Length
task.Size = summary.Size
// task := p.GetDownloadById("")
// bss, _ := json.Marshal(m.Data)
// summary := model.FileSummaryModel{}
// err := json.Unmarshal(bss, &summary)
// if err != nil {
// fmt.Println(err)
// }
// task.Hash = summary.Hash
// task.Length = summary.Length
// task.Size = summary.Size
p.SaveDownloadState(task)
// p.SaveDownloadState(task)
}
func AsyncUDPConnect(dst *net.UDPAddr) {
for {
time.Sleep(2 * time.Second)
if _, err := UDPconn.WriteToUDP([]byte(dst.IP.String()+" is ok"), dst); err != nil {
if _, err := UDPConn.WriteToUDP([]byte(dst.IP.String()+" is ok"), dst); err != nil {
log.Println("send msg fail", err)
return
} else {
@ -518,9 +388,13 @@ func UDPService() {
KeepAlive: true,
}
srcAddr := &net.UDPAddr{
IP: net.IPv4zero, Port: 9902} //注意端口必须固定
fmt.Println(srcAddr.String())
listener, err := quic.ListenAddr(srcAddr.String(), generateTLSConfig(), quicConfig)
IP: net.IPv4zero, Port: 9904} //注意端口必须固定
var err error
UDPConn, err = net.ListenUDP("udp", srcAddr)
if err != nil {
fmt.Println(err)
}
listener, err := quic.Listen(UDPConn, generateTLSConfig(), quicConfig)
if err != nil {
fmt.Println(err)
}
@ -531,6 +405,7 @@ func UDPService() {
if err != nil {
panic(err)
}
for {
select {
case <-ctx.Done():
@ -590,10 +465,8 @@ func UDPService() {
//处理内容
func ProcessingContent(stream quic.Stream) {
//需要处理关闭问题
for {
prefixByte := make([]byte, 4)
prefixByte := make([]byte, 6)
c1, err := io.ReadFull(stream, prefixByte)
fmt.Println(c1)
if err != nil {
@ -619,13 +492,22 @@ func ProcessingContent(stream quic.Stream) {
//什么也不做
continue
} else if m.Type == "directory" {
list := MyService.ZiMa().GetDirPath(m.Data.(string))
var list []model.Path
if m.Data.(string) == "" || m.Data.(string) == "/" {
for _, v := range config.FileSettingInfo.ShareDir {
tempList := MyService.ZiMa().GetDirPath(v)
list = append(list, tempList...)
}
} else {
list = MyService.ZiMa().GetDirPath(m.Data.(string))
}
m.To = m.From
m.Data = list
m.From = config.ServerInfo.Token
SendData(stream, m)
break
} else if m.Type == "file_data" {
SendFileData(stream, m.Data.(string), m.From, m.UUId)
break
} else if m.Type == types.PERSONADDFRIEND {
@ -636,7 +518,7 @@ func ProcessingContent(stream quic.Stream) {
fmt.Println(err)
continue
}
go MyService.Friend().UpdateAddFriendType(friend)
go MyService.Friend().UpdateOrCreate(friend)
mi := model2.FriendModel{}
mi.Avatar = config.UserInfo.Avatar
mi.Profile = config.UserInfo.Description
@ -647,6 +529,23 @@ func ProcessingContent(stream quic.Stream) {
m.From = config.ServerInfo.Token
SendData(stream, m)
break
} else if m.Type == "connection" {
UDPAddressMap[m.From] = m.Data.(string)
fmt.Println("persion", m)
mi := model2.FriendModel{}
mi.Avatar = config.UserInfo.Avatar
mi.Profile = config.UserInfo.Description
mi.Name = config.UserInfo.UserName
mi.Token = config.ServerInfo.Token
msg := model.MessageModel{}
msg.Type = types.PERSONADDFRIEND
msg.Data = mi
msg.To = m.From
msg.From = config.ServerInfo.Token
msg.UUId = m.UUId
Dial(m.Data.(string), msg)
break
} else {
//不应有不做返回的数据
@ -673,20 +572,43 @@ func SendFileData(stream quic.Stream, filePath, to, uuid string) error {
fmt.Println("读取失败", err)
return err
}
//先发送文件摘要
summary := model.FileSummaryModel{}
summary.BlockSize = blockSize
summary.Hash = file.GetHashByPath(filePath)
summary.Length = length
summary.Name = fStat.Name()
summary.Size = fStat.Size()
msg := model.MessageModel{}
msg.Type = "summary"
msg.Data = summary
msg.From = config.ServerInfo.Token
msg.To = to
msg.UUId = uuid
summaryByte, _ := json.Marshal(msg)
summaryPrefixLength := file.PrefixLength(len(summaryByte))
summaryData := append(summaryPrefixLength, summaryByte...)
stream.Write(summaryData)
bufferedReader := bufio.NewReader(f)
buf := make([]byte, blockSize)
for i := 0; i < length; i++ {
tran := model.TranFileModel{}
_, err = bufferedReader.Read(buf)
n, err := bufferedReader.Read(buf)
if err == io.EOF {
fmt.Println("读取完毕", err)
}
tran.Hash = file.GetHashByContent(buf)
tran.Hash = file.GetHashByContent(buf[:n])
tran.Index = i
tran.Length = length
msg := model.MessageModel{}
msg.Type = "file_data"
@ -695,7 +617,10 @@ func SendFileData(stream quic.Stream, filePath, to, uuid string) error {
msg.To = to
msg.UUId = uuid
b, _ := json.Marshal(msg)
stream.Write(b)
prefixLength := file.PrefixLength(len(b))
dataLength := file.DataLength(len(buf[:n]))
data := append(append(append(prefixLength, b...), dataLength...), buf[:n]...)
stream.Write(data)
}
defer stream.Close()
return nil

View file

@ -34,6 +34,7 @@ type Repository interface {
Search() SearchService
Person() PersonService
Friend() FriendService
Download() DownloadService
}
func NewService(db *gorm.DB, log loger2.OLog) Repository {
@ -57,6 +58,7 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
search: NewSearchService(),
person: NewPersonService(db),
friend: NewFriendService(db),
download: NewDownloadService(db),
}
}
@ -79,8 +81,12 @@ type store struct {
search SearchService
person PersonService
friend FriendService
download DownloadService
}
func (c *store) Download() DownloadService {
return c.download
}
func (c *store) Friend() FriendService {
return c.friend
}

View file

@ -5,7 +5,6 @@ import (
"fmt"
"net/url"
"reflect"
"strings"
"time"
"github.com/IceWhaleTech/CasaOS/model"
@ -53,7 +52,7 @@ func SocketConnect() {
m.To = msa.From
m.Type = types.PERSONADDFRIEND
m.UUId = uuid
result, err := Dial("192.168.2.225:9902", m)
result, err := Dial("192.168.2.224:9902", m)
friend := model2.FriendModel{}
if err != nil && !reflect.DeepEqual(result, friend) {
dataModelByte, _ := json.Marshal(result.Data)
@ -91,14 +90,14 @@ func SocketConnect() {
}
func Connect() {
host := strings.Split(config.ServerInfo.Handshake, "://")
u := url.URL{Scheme: "ws", Host: host[1], Path: "/v1/ws"}
u := url.URL{Scheme: "ws", Host: config.ServerInfo.Handshake + ":8088", Path: "/v1/ws"}
for {
d, _, e := websocket.DefaultDialer.Dial(u.String(), nil)
if e == nil {
WebSocketConn = d
return
}
fmt.Println(e)
time.Sleep(time.Second * 5)
}
}

View file

@ -10,19 +10,23 @@ import (
"io"
"io/ioutil"
"net"
"os"
"strconv"
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/lucas-clemente/quic-go"
uuid "github.com/satori/go.uuid"
)
var UDPconn *net.UDPConn
var UDPConn *net.UDPConn
var PeopleMap map[string]quic.Stream
var Message chan model.MessageModel
var UDPAddressMap map[string]string
func Dial(addr string, msg model.MessageModel) (m model.MessageModel, err error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@ -37,8 +41,18 @@ func Dial(addr string, msg model.MessageModel) (m model.MessageModel, err error)
NextProtos: []string{"bench"},
SessionTicketsDisabled: true,
}
srcAddr := &net.UDPAddr{
IP: net.IPv4zero, Port: 9904} //注意端口必须固定
//addr
if len(addr) == 0 {
addr = config.ServerInfo.Handshake + ":9527"
}
dstAddr, err := net.ResolveUDPAddr("udp", addr)
session, err := quic.DialAddrContext(ctx, addr, tlsConf, quicConfig)
//DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6"如果laddr不是nil将使用它作为本地地址否则自动选择一个本地地址。
//(conn)UDPConn代表一个UDP网络连接实现了Conn和PacketConn接口
session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), tlsConf, quicConfig)
if err != nil {
return m, err
}
@ -79,11 +93,12 @@ func SendData(stream quic.Stream, m model.MessageModel) {
stream.Write(data)
}
var Summary map[string]model.FileSummaryModel
//读取数据
func ReadContent(stream quic.Stream) {
path := ""
for {
prefixByte := make([]byte, 4)
prefixByte := make([]byte, 6)
c1, err := io.ReadFull(stream, prefixByte)
fmt.Println(c1, err, string(prefixByte))
prefixLength, err := strconv.Atoi(string(prefixByte))
@ -96,7 +111,7 @@ func ReadContent(stream quic.Stream) {
if err != nil {
fmt.Println(err)
}
fmt.Println(m)
//传输数据需要继续读取
if m.Type == "file_data" {
dataModelByte, _ := json.Marshal(m.Data)
@ -121,13 +136,80 @@ func ReadContent(stream quic.Stream) {
fmt.Println("hash不匹配", hash, dataModel.Hash)
}
filepath := path + strconv.Itoa(dataModel.Index)
tempPath := config.AppInfo.RootPath + "/temp" + "/" + m.UUId
file.IsNotExistMkDir(tempPath)
filepath := tempPath + "/" + strconv.Itoa(dataModel.Index)
tempFile, err := os.Stat(filepath)
if os.IsNotExist(err) || tempFile.Size() == 0 {
err = ioutil.WriteFile(filepath, dataByte, 0644)
if dataModel.Index >= (dataModel.Length - 1) {
//file.SpliceFiles("", path, dataModel.Length)
} else {
if file.GetHashByPath(filepath) != dataModel.Hash {
os.Remove(filepath)
err = ioutil.WriteFile(filepath, dataByte, 0644)
}
}
files, err := ioutil.ReadDir(tempPath)
if len(files) >= dataModel.Length {
summary := Summary[m.UUId]
file.SpliceFiles(tempPath, config.FileSettingInfo.DownloadDir+"/"+summary.Name, dataModel.Length, 0)
if file.GetHashByPath(config.FileSettingInfo.DownloadDir+"/"+summary.Name) == summary.Hash {
file.RMDir(tempPath)
task := model2.PersionDownloadDBModel{}
task.UUID = m.UUId
task.State = types.DOWNLOADFINISH
MyService.Download().EditDownloadState(task)
} else {
os.Remove(config.FileSettingInfo.DownloadDir + "/" + summary.Name)
task := model2.PersionDownloadDBModel{}
task.UUID = m.UUId
task.State = types.DOWNLOADERROR
MyService.Download().EditDownloadState(task)
}
break
}
} else if m.Type == "summary" {
dataModel := model.FileSummaryModel{}
if m.UUId == m.UUId {
dataModelByte, _ := json.Marshal(m.Data)
err := json.Unmarshal(dataModelByte, &dataModel)
fmt.Println(err)
}
task := model2.PersionDownloadDBModel{}
task.UUID = m.UUId
task.Name = dataModel.Name
task.Length = dataModel.Length
task.Size = dataModel.Size
task.State = types.DOWNLOADING
task.BlockSize = dataModel.BlockSize
task.Hash = dataModel.Hash
task.Type = 0
MyService.Download().SaveDownload(task)
Summary[m.UUId] = dataModel
} else if m.Type == "connection" {
UDPAddressMap[m.From] = m.Data.(string)
fmt.Println("udpconn", m)
mi := model2.FriendModel{}
mi.Avatar = config.UserInfo.Avatar
mi.Profile = config.UserInfo.Description
mi.Name = config.UserInfo.UserName
mi.Token = config.ServerInfo.Token
msg := model.MessageModel{}
msg.Type = types.PERSONADDFRIEND
msg.Data = mi
msg.To = m.From
msg.From = config.ServerInfo.Token
msg.UUId = m.UUId
Dial(m.Data.(string), msg)
Message <- m
break
} else {
Message <- m
}