From 5177c4b601a4203cf7e4185dd43418b152b5f789 Mon Sep 17 00:00:00 2001 From: Askill Date: Sun, 29 May 2022 11:34:43 +0200 Subject: [PATCH] reduced number of structs, 2 endpoints, timeout due to no keepalive ping from server --- go/server.go | 65 +++++++++++++++++++++-------------------- go/util.go | 73 ++++++++++++++++++----------------------------- python/clients.py | 14 +++++---- 3 files changed, 67 insertions(+), 85 deletions(-) diff --git a/go/server.go b/go/server.go index 424d27b..be66156 100644 --- a/go/server.go +++ b/go/server.go @@ -5,7 +5,6 @@ import ( "flag" "log" "net/http" - "sync" "time" "github.com/gorilla/websocket" @@ -15,19 +14,29 @@ var upgrader = websocket.Upgrader{ ReadBufferSize: 2048, WriteBufferSize: 2048, } -var img = GetImage(10, 10) +var img = GetImage(1000, 1000) -func write(ticker time.Ticker, c *websocket.Conn, wg *sync.WaitGroup) { - defer wg.Done() +func get(w http.ResponseWriter, r *http.Request) { + c, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Print("error while upgrading", err) + return + } + defer c.Close() + ticker := time.NewTicker(1 * time.Second) + + var refImage = GetImage(img.width, img.height) var tmpImage = GetImage(img.width, img.height) + for range ticker.C { - diff := tmpImage.GetDiff(&img) - for i := 0; i < int(diff.Width*diff.Height); i++ { - pix := diff.Pixels[i] - if pix.UserID != 0 { - x := uint16(i / int(diff.Width)) - y := uint16(i % int(diff.Height)) - msg := Message{X: x, Y: y, Timestamp: pix.Timestamp, UserID: pix.UserID, Color: pix.Color} + copy(refImage.pixels, img.pixels) + diff := tmpImage.GetDiff(&refImage) + for i := 0; i < int(diff.width*diff.height); i++ { + pix := diff.pixels[i] + if pix.pixel.UserID != 0 { + x := i / int(diff.width) + y := i % int(diff.height) + msg := Message{X: uint32(x), Y: uint32(y), Timestamp: pix.pixel.Timestamp, UserID: pix.pixel.UserID, Color: pix.pixel.Color} marshalMsg, err := json.Marshal(msg) if err != nil { log.Println("error while writing image", err) @@ -36,12 +45,17 @@ func write(ticker time.Ticker, c *websocket.Conn, wg *sync.WaitGroup) { err = c.WriteMessage(1, marshalMsg) } } - copy(img.pixels, tmpImage.pixels) + copy(tmpImage.pixels, refImage.pixels) } } -func read(c *websocket.Conn, wg *sync.WaitGroup) { - defer wg.Done() +func set(w http.ResponseWriter, r *http.Request) { + c, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Print("error while upgrading", err) + return + } + defer c.Close() for { _, msg, err := c.ReadMessage() if err != nil { @@ -50,35 +64,20 @@ func read(c *websocket.Conn, wg *sync.WaitGroup) { } message := Message{} - message.JsonToStruct(msg) + json.Unmarshal(msg, &message) + img.SetPixel(message) } } -func serve(w http.ResponseWriter, r *http.Request) { - c, err := upgrader.Upgrade(w, r, nil) - if err != nil { - log.Print("error while upgrading", err) - return - } - defer c.Close() - ticker := time.NewTicker(1 * time.Second) - var wg sync.WaitGroup - - // end fucntion if either of the 2 functions is done - wg.Add(1) - go write(*ticker, c, &wg) - go read(c, &wg) - wg.Wait() -} - func main() { var addr = flag.String("addr", "localhost:8080", "http service address") flag.Parse() log.SetFlags(0) log.Println("starting server on", *addr) - http.HandleFunc("/", serve) + http.HandleFunc("/get", get) + http.HandleFunc("/set", set) log.Fatal(http.ListenAndServe(*addr, nil)) } diff --git a/go/util.go b/go/util.go index cc44dc3..fb840db 100644 --- a/go/util.go +++ b/go/util.go @@ -1,71 +1,50 @@ package main import ( - "encoding/json" "fmt" "sync" ) type Message struct { - X uint16 `json:"x"` - Y uint16 `json:"y"` + X uint32 `json:"x"` + Y uint32 `json:"y"` Color uint8 `json:"color"` Timestamp int64 `json:"timestamp"` UserID uint64 `json:"userid"` } -func (message *Message) JsonToStruct(input []byte) *Message { - json.Unmarshal(input, message) - return message -} - type pixel struct { Color uint8 `json:"color"` Timestamp int64 `json:"timestamp"` UserID uint64 `json:"userid"` - Mutex sync.Mutex +} + +type pixelContainer struct { + pixel pixel + Mutex sync.Mutex } type image struct { - width uint16 - height uint16 - pixels []pixel + width uint32 + height uint32 + pixels []pixelContainer } -type messagePixel struct { - Color uint8 `json:"color"` - Timestamp int64 `json:"timestamp"` - UserID uint64 `json:"userid"` -} -type messageImage struct { - Width uint16 `json:"width"` - Height uint16 `json:"height"` - Pixels []messagePixel `json:"pixel"` -} - -func GetMessageImage(w uint16, h uint16) messageImage { - pixels := make([]messagePixel, w*h) +func GetImage(w uint32, h uint32) image { + pixels := make([]pixelContainer, w*h) for i := 0; i < int(w*h); i++ { - pixels[i] = messagePixel{Color: 0, Timestamp: 0, UserID: 0} - } - return messageImage{Width: w, Height: h, Pixels: pixels} -} - -func GetImage(w uint16, h uint16) image { - pixels := make([]pixel, w*h) - for i := 0; i < int(w*h); i++ { - pixels[i] = pixel{Color: 0, Timestamp: 0, UserID: 0, Mutex: sync.Mutex{}} + pixels[i] = pixelContainer{pixel: pixel{Color: 0, Timestamp: 0, UserID: 0}, Mutex: sync.Mutex{}} } return image{width: w, height: h, pixels: pixels} } -func (p *pixel) setColor(color uint8, timestamp int64, userid uint64) { +func (p *pixelContainer) setColor(color uint8, timestamp int64, userid uint64) { p.Mutex.Lock() defer p.Mutex.Unlock() - if timestamp > p.Timestamp { - p.Color = color - p.Timestamp = timestamp - p.UserID = userid + if timestamp > p.pixel.Timestamp { + p.pixel.Color = color + p.pixel.Timestamp = timestamp + p.pixel.UserID = userid } } @@ -83,17 +62,19 @@ func (img *image) SetPixel(message Message) *image { return img } -func comparePixels(pixel1 *pixel, pixel2 *pixel) bool { - return pixel1.Color == pixel2.Color && pixel1.Timestamp == pixel2.Timestamp && pixel1.UserID == pixel2.UserID +func comparePixels(pixel1 *pixelContainer, pixel2 *pixelContainer) bool { + return pixel1.pixel.Color == pixel2.pixel.Color && + pixel1.pixel.Timestamp == pixel2.pixel.Timestamp && + pixel1.pixel.UserID == pixel2.pixel.UserID } -func (img *image) GetDiff(img2 *image) messageImage { - diff := GetMessageImage(img.width, img.height) +func (img *image) GetDiff(img2 *image) image { + diff := GetImage(img.width, img.height) for i := 0; i < int(img.width*img.height); i++ { if !comparePixels(&img.pixels[i], &img2.pixels[i]) { - diff.Pixels[i].Color = img2.pixels[i].Color - diff.Pixels[i].UserID = img2.pixels[i].UserID - diff.Pixels[i].Timestamp = img2.pixels[i].Timestamp + diff.pixels[i].pixel.Color = img2.pixels[i].pixel.Color + diff.pixels[i].pixel.UserID = img2.pixels[i].pixel.UserID + diff.pixels[i].pixel.Timestamp = img2.pixels[i].pixel.Timestamp } } return diff diff --git a/python/clients.py b/python/clients.py index 4e6c543..b933dfa 100644 --- a/python/clients.py +++ b/python/clients.py @@ -20,30 +20,32 @@ class pixel: userid: int async def sender(): - async with websockets.connect("ws://localhost:8080/") as websocket: + async with websockets.connect("ws://localhost:8080/set") as websocket: while True: message = pixel( - x=random.randint(0, 9), - y=random.randint(0, 9), + x=random.randint(0, 990), + y=random.randint(0, 990), color=random.randint(0,15), timestamp=int(time.time()), userid=1, ) await websocket.send(json.dumps(message.__dict__)) + await asyncio.sleep(0.1) async def client(): - async with websockets.connect("ws://localhost:8080/") as websocket: + async with websockets.connect("ws://localhost:8080/get") as websocket: i= 0 while True: i+=1 x = await websocket.recv() - print(i, pixel(**json.loads(x))) + #print(i, x) async def main(): - coros = [sender() for _ in range(100)] + coros = [sender() for _ in range(500)] coros.append(client()) returns = await asyncio.gather(*coros) + if __name__ == "__main__": asyncio.get_event_loop().run_until_complete(main())