123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- package main
- import (
- "log"
- "time"
- "git.ali33.ru/fcg-xvii/go-tools/json"
- "github.com/gorilla/websocket"
- "golang.org/x/net/context"
- )
- type WSClient struct {
- clients *WSClients
- conn *websocket.Conn
- ctx context.Context
- cancel context.CancelFunc
- //callClose func(*WSClient)
- //callIncoming func(*WSClient, json.Map)
- }
- func (s *WSClient) SendData(data json.Map) error {
- w, err := s.conn.NextWriter(websocket.TextMessage)
- if err != nil {
- return err
- }
- _, err = w.Write(data.JSON())
- w.Close()
- return err
- }
- func (s *WSClient) SendSingle(data json.Map) error {
- jm := json.Map{
- "data": data,
- }
- return s.SendData(jm)
- }
- func (s *WSClient) SendMessage(data json.Map, deadline time.Duration) (<-chan json.Map, error) {
- dl := time.Now().Add(deadline)
- id := s.clients.nextID()
- jm := json.Map{
- "id": id,
- "data": data,
- }
- if err := s.SendData(jm); err != nil {
- return nil, err
- }
- ctx, _ := context.WithDeadline(context.Background(), dl)
- ch := make(chan json.Map)
- rch := make(chan json.Map)
- s.clients.rStore.Store(id, ch)
- go func() {
- select {
- case <-ctx.Done():
- s.clients.rStore.Delete(id)
- close(rch)
- case rData := <-ch:
- select {
- case rch <- rData:
- default:
- }
- }
- }()
- return rch, nil
- }
- func (s *WSClient) Context() context.Context {
- return s.ctx
- }
- func (s *WSClient) Read() <-chan *Message {
- ch := make(chan *Message, 10)
- go func() {
- defer func() {
- s.cancel()
- close(ch)
- }()
- for {
- t, src, err := s.conn.ReadMessage()
- log.Println(t, string(src), err)
- if err != nil {
- s.clients.clientDisconnected(s)
- return
- }
- var jm json.Map
- if err = json.Unmarshal(src, &jm); err == nil {
- if jm.Bool("is_response", false) {
- //log.Println("AAAAAAAAAAAAAAAAAAA")
- if rch, check := s.clients.rStore.LoadAndDelete(jm.Int("id", -1)); check {
- rch.(chan json.Map) <- jm.Map("data", json.Map{})
- }
- } else {
- //log.Println("UUUUUUUUUUUUUUUU")
- mes := MessageFromMap(jm, s)
- select {
- case ch <- mes:
- default:
- }
- }
- }
- }
- }()
- return ch
- }
- /////////////////////////
|