github.com/christoph-karpowicz/db_mediator@v0.0.0-20210207102849-61a28a1071d8/internal/server/application/websocket_handler.go (about)

     1  package application
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  
     9  	"github.com/gorilla/websocket"
    10  )
    11  
    12  const (
    13  	WS_REQ_GETSYNCHLIST = "getSynchsList"
    14  	WS_REQ_STARTSYNCH   = "startSynch"
    15  	WS_REQ_STOPSYNCH    = "stopSynch"
    16  )
    17  
    18  type wsInbound struct {
    19  	ID   string        `yaml:"id"`
    20  	Name string        `yaml:"name"`
    21  	Data wsInboundData `yaml:"data"`
    22  }
    23  
    24  type wsInboundData struct {
    25  	Payload string `yaml:"payload"`
    26  }
    27  
    28  type wsOutbound struct {
    29  	ID      string         `yaml:"id"`
    30  	Name    string         `yaml:"name"`
    31  	Success bool           `yaml:"success"`
    32  	Data    wsOutboundData `yaml:"data"`
    33  }
    34  
    35  type wsOutboundData struct {
    36  	Message string `yaml:"message"`
    37  	Payload string `yaml:"payload"`
    38  }
    39  
    40  var wsUpgrader = websocket.Upgrader{
    41  	ReadBufferSize:  1024,
    42  	WriteBufferSize: 1024,
    43  }
    44  
    45  type webSocketHandler struct {
    46  	app *Application
    47  }
    48  
    49  func (wsh *webSocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    50  	wsUpgrader.CheckOrigin = func(r *http.Request) bool { return true }
    51  
    52  	ws, err := wsUpgrader.Upgrade(w, r, nil)
    53  	if err != nil {
    54  		panic(err)
    55  	}
    56  	log.Println("Client Connected")
    57  
    58  	if wsh.app == nil {
    59  		log.Println("err")
    60  	}
    61  
    62  	go wsh.wsReader(ws)
    63  }
    64  
    65  func (wsh *webSocketHandler) wsReader(ws *websocket.Conn) {
    66  	for {
    67  		messageType, message, err := ws.ReadMessage()
    68  		if err != nil {
    69  			log.Println(err)
    70  			return
    71  		}
    72  		var wsReq wsInbound
    73  		marshalErr := json.Unmarshal(message, &wsReq)
    74  		if marshalErr != nil {
    75  			// panic(marshalErr)
    76  		}
    77  		fmt.Println(wsReq)
    78  		wsh.dispatchWsRequest(ws, &wsReq, messageType)
    79  	}
    80  }
    81  
    82  func (wsh *webSocketHandler) dispatchWsRequest(ws *websocket.Conn, wsReq *wsInbound, messageType int) {
    83  	var wsOut wsOutbound
    84  
    85  	switch wsReq.Name {
    86  	case WS_REQ_GETSYNCHLIST:
    87  		synchsList := wsh.app.listSynchsToJSON()
    88  		wsOut = wsOutbound{
    89  			ID:      wsReq.ID,
    90  			Name:    "synchsListFetched",
    91  			Success: true,
    92  			Data: wsOutboundData{
    93  				Payload: string(synchsList),
    94  			},
    95  		}
    96  	case WS_REQ_STARTSYNCH:
    97  		synchName := wsReq.Data.Payload
    98  
    99  		responseChan := createResponseChannel()
   100  		go wsh.app.runSynch(responseChan, "one-off", synchName, true)
   101  		// response := <-responseChan
   102  
   103  		wsOut = wsOutbound{
   104  			ID:      wsReq.ID,
   105  			Name:    "synchStarted",
   106  			Success: true,
   107  			Data:    wsOutboundData{
   108  				// Message: response.(string),
   109  			},
   110  		}
   111  	case WS_REQ_STOPSYNCH:
   112  		synchName := wsReq.Data.Payload
   113  
   114  		responseChan := createResponseChannel()
   115  		go wsh.app.stopSynch(responseChan, synchName)
   116  		// response := <-responseChan
   117  
   118  		wsOut = wsOutbound{
   119  			ID:      wsReq.ID,
   120  			Name:    "synchStopped",
   121  			Success: true,
   122  			Data:    wsOutboundData{
   123  				// Message: response.(string),
   124  			},
   125  		}
   126  	default:
   127  		wsOut = wsOutbound{
   128  			ID:      wsReq.ID,
   129  			Name:    "unknownRequest",
   130  			Success: false,
   131  			Data: wsOutboundData{
   132  				Message: "Unknown websocket request name \"" + wsReq.Name + "\".",
   133  			},
   134  		}
   135  	}
   136  
   137  	wsOutJSON, err := json.Marshal(wsOut)
   138  	if err != nil {
   139  		panic(err)
   140  	}
   141  
   142  	if err := ws.WriteMessage(messageType, wsOutJSON); err != nil {
   143  		log.Println(err)
   144  		return
   145  	}
   146  }