123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- package main
- import (
- "context"
- "flag"
- "fmt"
- "log"
- "math/rand"
- "net"
- "net/http"
- "google.golang.org/grpc"
- "google.golang.org/grpc/grpclog"
- "google.golang.org/grpc/credentials"
- "google.golang.org/grpc/examples/data"
- // "github.com/improbable-eng/grpc-web/go/grpcweb"
- _ "net/http/pprof"
- pb "git.capella.pro/thepaint/protos"
- "encoding/base64"
- "encoding/json"
- "github.com/improbable-eng/grpc-web/go/grpcweb"
- "github.com/pion/webrtc/v3"
- "github.com/sirupsen/logrus"
- )
- var (
- tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
- certFile = flag.String("cert_file", "", "The TLS cert file")
- keyFile = flag.String("key_file", "", "The TLS key file")
- jsonDBFile = flag.String("json_db_file", "", "A json file containing a list of features")
- port = flag.Int("port", 8080, "The server port")
- )
- type server struct {
- pb.UnimplementedPaintClientServer
- // savedFeatures []*pb.Feature // read-only after initialized
- //
- // mu sync.Mutex // protects routeNotes
- // routeNotes map[string][]*pb.RouteNote
- }
- func main() {
- grpclog.V(10)
- flag.Parse()
- lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
- if err != nil {
- log.Fatalf("failed to listen: %v", err)
- }
- var opts []grpc.ServerOption
- if *tls {
- if *certFile == "" {
- *certFile = data.Path("x509/server_cert.pem")
- }
- if *keyFile == "" {
- *keyFile = data.Path("x509/server_key.pem")
- }
- creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
- if err != nil {
- log.Fatalf("Failed to generate credentials %v", err)
- }
- opts = []grpc.ServerOption{grpc.Creds(creds)}
- }
- grpcServer := grpc.NewServer(opts...)
- s := newServer()
- pb.RegisterPaintClientServer(grpcServer, s)
- logrus.Printf("starting %d", *port)
- wrappedServer := grpcweb.WrapServer(grpcServer,
- grpcweb.WithOriginFunc(func(origin string) bool { return true }),
- grpcweb.WithWebsocketsMessageReadLimit(100000))
- handler := func(resp http.ResponseWriter, req *http.Request) {
- logrus.Info(req)
- if req.ProtoMajor != 2 {
- wrappedServer.ServeHTTP(resp, req)
- } else {
- grpcServer.ServeHTTP(resp, req)
- }
- }
- httpServer := http.Server{
- Addr: fmt.Sprintf(":%d", port),
- // Handler: CompressHandler(http.HandlerFunc(handler)),
- Handler: http.HandlerFunc(handler),
- }
- go func() {
- http.ListenAndServe(":8081", nil)
- }()
- if err := httpServer.Serve(lis); err != nil {
- grpclog.Fatalf("failed starting http server: %v", err)
- }
- }
- func (s *server) Paint(ctx context.Context, request *pb.PaintRequest) (*pb.PaintReply, error) {
- panic("implement me")
- }
- func (s *server) Monitor(sub *pb.MonitorSub, monitorServer pb.PaintClient_MonitorServer) error {
- // for k := 0; k < 4; k++ {
- // points := []*pb.MonitorPoint{}
- // for i := 64*k; i < 64*(k+1); i++ {
- // for j := 0; j < 256; j++ {
- // points = append(points, &pb.MonitorPoint{
- // Point: &pb.BPoint{
- // X: int32(i),
- // Y: int32(j),
- // },
- // Color: &pb.BColor{
- // Rgba: uint32(rand.Intn(256)) | uint32(rand.Intn(256))<<8 | uint32(rand.Intn(256))<<16 | 255<<24,
- // },
- // })
- // }
- // }
- //
- // monitorServer.Send(&pb.MonitorReply{
- // Points: points,
- // // BytesPoints: b.Bytes(),
- // })
- // }
- points := []*pb.MonitorPoint{}
- for i := 0; i < 256; i++ {
- for j := 0; j < 256; j++ {
- points = append(points, &pb.MonitorPoint{
- Point: &pb.BPoint{
- X: int32(i),
- Y: int32(j),
- },
- Color: &pb.BColor{
- Rgba: uint32(rand.Intn(256)) | uint32(rand.Intn(256))<<8 | uint32(rand.Intn(256))<<16 | 255<<24,
- },
- })
- }
- }
- monitorServer.Send(&pb.MonitorReply{
- Points: points,
- // BytesPoints: b.Bytes(),
- })
- return nil
- }
- // func (s *server) RequestRTC(req pb.PaintClient_RequestRTCServer) error {
- // offer(req)
- // return nil
- // }
- func newServer() *server {
- s := &server{}
- return s
- }
- func handleError(err error) {
- logrus.Error(err)
- }
- func (s *server) RequestRTC(stream pb.PaintClient_RequestRTCServer) error {
- logrus.Info("NEW GRPC")
- // Configure and create a new PeerConnection.
- config := webrtc.Configuration{
- ICEServers: []webrtc.ICEServer{
- {
- URLs: []string{"stun:melvans.com:3478"},
- Username: "b84e4232f84505e3c3967184df374f2cdaa954f1",
- Credential: "afc39ae0591c132292f73a87f6f3725311fbafa0",
- // URLs: []string{"stun:stun.l.google.com:19302"},
- },
- },
- }
- pc, err := webrtc.NewPeerConnection(config)
- if err != nil {
- handleError(err)
- }
- // Create DataChannel.
- sendChannel, err := pc.CreateDataChannel("data", nil)
- if err != nil {
- handleError(err)
- }
- sendChannel.OnClose(func() {
- logrus.Println("sendChannel has closed")
- })
- sendChannel.OnOpen(func() {
- logrus.Println("sendChannel has opened")
- })
- sendChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
- logrus.Println(string(msg.Data))
- })
- // Create offer
- offer, err := pc.CreateOffer(nil)
- if err != nil {
- handleError(err)
- }
- if err := pc.SetLocalDescription(offer); err != nil {
- handleError(err)
- }
- // Add handlers for setting up the connection.
- pc.OnICEConnectionStateChange(func(state webrtc.ICEConnectionState) {
- logrus.Println(state)
- })
- // connectionString := make(chan bool)
- // Trickle ICE. Emit server candidate to client
- pc.OnICECandidate(func(i *webrtc.ICECandidate) {
- if i == nil {
- return
- }
- // candidateString, err := json.Marshal(i.ToJSON())
- // if err != nil {
- // logrus.Error(err)
- // return
- // }
- logrus.Println(i)
- err = stream.Send(&pb.RTCData{
- Event: string(pc.LocalDescription().Type.String()),
- Data: string(pc.LocalDescription().SDP),
- })
- // connectionString <- true
- if err != nil {
- logrus.Error(err)
- return
- }
- })
- for {
- msg, err := stream.Recv()
- if err != nil {
- logrus.Error(err)
- return err
- }
- answer := webrtc.SessionDescription{
- SDP: msg.Data,
- Type: webrtc.NewSDPType(msg.Event),
- }
- err = pc.SetRemoteDescription(answer)
- if err != nil {
- logrus.Error(err)
- return err
- }
- }
- // // If PeerConnection is closed remove it from global list
- // pc.OnConnectionStateChange(func(p webrtc.PeerConnectionState) {
- // switch p {
- // case webrtc.PeerConnectionStateFailed:
- // if err := pc.Close(); err != nil {
- // log.Print(err)
- // }
- // case webrtc.PeerConnectionStateClosed:
- // log.Print("closed")
- // }
- // })
- // offer, err := pc.CreateOffer(nil)
- // if err != nil {
- // logrus.Error(err)
- // }
- // if err = pc.SetLocalDescription(offer); err != nil {
- // logrus.Error(err)
- // }
- // logrus.Println(offer)
- // <-connectionString
- // answer := webrtc.SessionDescription{
- // SDP: sub.Data,
- // Type: webrtc.SDPTypeAnswer,
- // }
- // err = pc.SetRemoteDescription(answer)
- // if err != nil {
- // logrus.Error(err)
- // }
- // return nil
- }
- func Encode(obj interface{}) string {
- b, err := json.Marshal(obj)
- if err != nil {
- panic(err)
- }
- return base64.StdEncoding.EncodeToString(b)
- }
- func websocketHandler(w http.ResponseWriter, r *http.Request) {
- }
|