main.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package main
  2. import (
  3. "log"
  4. "math/rand"
  5. "net/http"
  6. "sync"
  7. // "github.com/improbable-eng/grpc-web/go/grpcweb"
  8. _ "net/http/pprof"
  9. pb "git.capella.pro/thepaint/protos"
  10. "google.golang.org/protobuf/proto"
  11. "encoding/base64"
  12. "encoding/json"
  13. "github.com/gorilla/websocket"
  14. "github.com/pion/webrtc/v3"
  15. "github.com/sirupsen/logrus"
  16. )
  17. var upgrader = websocket.Upgrader{
  18. CheckOrigin: func(r *http.Request) bool { return true },
  19. }
  20. func main() {
  21. http.HandleFunc("/ws", websocketHandler)
  22. logrus.Fatal(http.ListenAndServe(":8081", nil))
  23. }
  24. func Getp(ii int, jj int) []*pb.MonitorPoint {
  25. points := []*pb.MonitorPoint{}
  26. for i := ii * 32; i < 32*(1+ii); i++ {
  27. for j := jj * 32; j < 32*(1+jj); j++ {
  28. points = append(points, &pb.MonitorPoint{
  29. Point: &pb.BPoint{
  30. X: int32(i),
  31. Y: int32(j),
  32. },
  33. Color: &pb.BColor{
  34. Rgba: uint32(rand.Intn(256)) | uint32(rand.Intn(256))<<8 | uint32(rand.Intn(256))<<16 | 255<<24,
  35. },
  36. })
  37. }
  38. }
  39. return points
  40. }
  41. func Encode(obj interface{}) string {
  42. b, err := json.Marshal(obj)
  43. if err != nil {
  44. panic(err)
  45. }
  46. return base64.StdEncoding.EncodeToString(b)
  47. }
  48. // Handle incoming websockets
  49. func websocketHandler(w http.ResponseWriter, r *http.Request) {
  50. // Upgrade HTTP request to Websocket
  51. unsafeConn, err := upgrader.Upgrade(w, r, nil)
  52. if err != nil {
  53. log.Print("upgrade:", err)
  54. return
  55. }
  56. c := &threadSafeWriter{unsafeConn, sync.Mutex{}}
  57. logrus.Info("NEW GRPC")
  58. // Configure and create a new PeerConnection.
  59. config := webrtc.Configuration{
  60. ICEServers: []webrtc.ICEServer{
  61. {
  62. URLs: []string{"stun:melvans.com:3478"},
  63. Username: "b84e4232f84505e3c3967184df374f2cdaa954f1",
  64. Credential: "afc39ae0591c132292f73a87f6f3725311fbafa0",
  65. // URLs: []string{"stun:stun.l.google.com:19302"},
  66. },
  67. },
  68. }
  69. pc, err := webrtc.NewPeerConnection(config)
  70. if err != nil {
  71. logrus.Error(err)
  72. }
  73. // Create DataChannel.
  74. f := false
  75. sendChannel, err := pc.CreateDataChannel("data", &webrtc.DataChannelInit{
  76. Ordered: &f,
  77. })
  78. if err != nil {
  79. logrus.Error(err)
  80. }
  81. sendChannel.OnClose(func() {
  82. logrus.Println("sendChannel has closed")
  83. })
  84. sendChannel.OnOpen(func() {
  85. logrus.Println("sendChannel has opened")
  86. })
  87. sendChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
  88. data := &pb.WebRTCRequest{}
  89. err := proto.Unmarshal(msg.Data, data)
  90. if err != nil {
  91. logrus.WithField("data", data).Error(err)
  92. return
  93. }
  94. logrus.WithField("data", data).Info("req")
  95. if data.GetRequestData() != nil {
  96. for i := 0; i < 8; i++ {
  97. for j := 0; j < 8; j++ {
  98. data := &pb.MonitorReply{
  99. Points: Getp(i, j),
  100. }
  101. md, err := proto.Marshal(data)
  102. if err != nil {
  103. logrus.Error(err)
  104. continue
  105. }
  106. logrus.Info(len(md))
  107. sendChannel.Send(md)
  108. // err = sendChannel.Send(md)
  109. // if err != nil {
  110. // logrus.Error(err)
  111. // continue
  112. // }
  113. }
  114. }
  115. }
  116. })
  117. // Create a video track
  118. videoTrack, err := webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP8}, "video", "pion")
  119. if err != nil {
  120. panic(err)
  121. }
  122. _, err = pc.AddTrack(videoTrack)
  123. if err != nil {
  124. panic(err)
  125. }
  126. // Create offer
  127. offer, err := pc.CreateOffer(nil)
  128. if err != nil {
  129. logrus.Error(err)
  130. }
  131. if err := pc.SetLocalDescription(offer); err != nil {
  132. logrus.Error(err)
  133. }
  134. // Add handlers for setting up the connection.
  135. pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
  136. logrus.Println(state)
  137. })
  138. // connectionString := make(chan bool)
  139. // Trickle ICE. Emit server candidate to client
  140. pc.OnICECandidate(func(i *webrtc.ICECandidate) {
  141. if i == nil {
  142. return
  143. }
  144. data := &pb.RTCData{
  145. Event: string(pc.LocalDescription().Type.String()),
  146. Data: string(pc.LocalDescription().SDP),
  147. }
  148. logrus.WithField("data", data).Info("data to client")
  149. md, _ := proto.Marshal(data)
  150. w, _ := unsafeConn.NextWriter(websocket.BinaryMessage)
  151. w.Write(md)
  152. w.Close()
  153. })
  154. for {
  155. _, raw, err := c.ReadMessage()
  156. data := &pb.RTCData{}
  157. if err != nil {
  158. logrus.Error(err)
  159. return
  160. } else if err := proto.Unmarshal(raw, data); err != nil {
  161. logrus.WithField("data", string(raw)).Error(err)
  162. return
  163. }
  164. logrus.WithField("data", data).Info("data from client")
  165. switch data.Event {
  166. case "candidate":
  167. candidate := webrtc.ICECandidateInit{}
  168. if err := json.Unmarshal([]byte(data.Data), &candidate); err != nil {
  169. logrus.Error(err)
  170. return
  171. }
  172. if err := pc.AddICECandidate(candidate); err != nil {
  173. logrus.Error(err)
  174. return
  175. }
  176. case "answer":
  177. answer := webrtc.SessionDescription{
  178. Type: webrtc.NewSDPType(data.Event),
  179. SDP: data.Data,
  180. }
  181. if err := pc.SetRemoteDescription(answer); err != nil {
  182. logrus.Error(err)
  183. return
  184. }
  185. }
  186. }
  187. }
  188. type threadSafeWriter struct {
  189. *websocket.Conn
  190. sync.Mutex
  191. }
  192. func (t *threadSafeWriter) WriteJSON(v interface{}) error {
  193. t.Lock()
  194. defer t.Unlock()
  195. return t.Conn.WriteJSON(v)
  196. }