97 lines
1.7 KiB
Go
97 lines
1.7 KiB
Go
/**
|
|
* Created by IntelliJ IDEA.
|
|
* User: Ar.M
|
|
* Date: 2020-05-10
|
|
* Time: 22:13
|
|
*/
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"google.golang.org/grpc"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
transportpb "yunlian-file-transfer-demo/proto"
|
|
)
|
|
|
|
var filesDir string
|
|
|
|
func init() {
|
|
_, fp, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
log.Fatalf("Get caller failed")
|
|
}
|
|
filesDir = filepath.Join(filepath.Dir(fp), "files")
|
|
}
|
|
|
|
type server struct{}
|
|
|
|
func (s *server) Download(req *transportpb.FileRequest, stream transportpb.FileService_DownloadServer) error {
|
|
fileName := req.GetFileName()
|
|
fileRange := req.GetFileRange()
|
|
|
|
path := filepath.Join(filesDir, fileName)
|
|
|
|
fileInfo, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fileSize := fileInfo.Size()
|
|
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
if fileRange > 0 {
|
|
_, err = f.Seek(fileRange, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
log.Printf("read file at seek: %d\n", fileRange)
|
|
}
|
|
|
|
var totalBytesStreamed int64
|
|
|
|
for totalBytesStreamed < fileSize {
|
|
block := make([]byte, 1024)
|
|
bytesRead, err := f.Read(block)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := stream.Send(&transportpb.FileResponse{
|
|
Block: block,
|
|
FileSize: fileSize,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
totalBytesStreamed += int64(bytesRead)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
lis, err := net.Listen("tcp", "0.0.0.0:10086")
|
|
if err != nil {
|
|
log.Fatalf("Failed to listen on 10086 : %v\n", err)
|
|
}
|
|
|
|
s := grpc.NewServer()
|
|
transportpb.RegisterFileServiceServer(s, &server{})
|
|
|
|
fmt.Println("Starting server on 10086")
|
|
if err := s.Serve(lis); err != nil {
|
|
log.Fatalf("failed to start server : %v\n", err)
|
|
}
|
|
}
|