github.com/anycable/anycable-go@v1.5.1/protocol/protocol.go (about) 1 package protocol 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/anycable/anycable-go/common" 8 9 pb "github.com/anycable/anycable-go/protos" 10 ) 11 12 // NewConnectMessage builds a connect RPC payload from the session env 13 func NewConnectMessage(env *common.SessionEnv) *pb.ConnectionRequest { 14 return &pb.ConnectionRequest{ 15 Env: buildEnv(env), 16 } 17 } 18 19 // NewCommandMessage builds a command RPC payload from the session env, command and channel names, 20 // and connection identifiers 21 func NewCommandMessage(env *common.SessionEnv, command string, channel string, identifiers string, data string) *pb.CommandMessage { 22 msg := pb.CommandMessage{ 23 Command: command, 24 Env: buildChannelEnv(channel, env), 25 Identifier: channel, 26 ConnectionIdentifiers: identifiers, 27 } 28 29 if data != "" { 30 msg.Data = data 31 } 32 33 return &msg 34 } 35 36 // NewDisconnectMessage builds a disconnect RPC payload from the session env, connection identifiers and 37 // subscriptions 38 func NewDisconnectMessage(env *common.SessionEnv, identifiers string, subscriptions []string) *pb.DisconnectRequest { 39 return &pb.DisconnectRequest{ 40 Identifiers: identifiers, 41 Subscriptions: subscriptions, 42 Env: buildDisconnectEnv(env), 43 } 44 } 45 46 // ParseConnectResponse takes protobuf ConnectionResponse struct and converts into common.ConnectResult and/or error 47 func ParseConnectResponse(response *pb.ConnectionResponse) (*common.ConnectResult, error) { 48 reply := common.ConnectResult{Transmissions: response.Transmissions} 49 50 if response.Env != nil { 51 reply.CState = response.Env.Cstate 52 } 53 54 if response.Status.String() == "SUCCESS" { 55 reply.Identifier = response.Identifiers 56 reply.Status = common.SUCCESS 57 return &reply, nil 58 } 59 60 if response.Status.String() == "FAILURE" { 61 reply.Status = common.FAILURE 62 return &reply, nil 63 } 64 65 reply.Status = common.ERROR 66 return &reply, fmt.Errorf("Application error: %s", response.ErrorMsg) 67 } 68 69 // ParseCommandResponse takes protobuf CommandResponse struct and converts into common.CommandResult and/or error 70 func ParseCommandResponse(response *pb.CommandResponse) (*common.CommandResult, error) { 71 res := &common.CommandResult{ 72 Disconnect: response.Disconnect, 73 StopAllStreams: response.StopStreams, 74 Streams: response.Streams, 75 StoppedStreams: response.StoppedStreams, 76 Transmissions: response.Transmissions, 77 } 78 79 if response.Env != nil { 80 res.CState = response.Env.Cstate 81 res.IState = response.Env.Istate 82 } 83 84 if response.Status.String() == "SUCCESS" { 85 res.Status = common.SUCCESS 86 return res, nil 87 } 88 89 if response.Status.String() == "FAILURE" { 90 res.Status = common.FAILURE 91 return res, nil 92 } 93 94 res.Status = common.ERROR 95 return res, fmt.Errorf("Application error: %s", response.ErrorMsg) 96 } 97 98 // ParseDisconnectResponse takes protobuf DisconnectResponse struct and return error if any 99 func ParseDisconnectResponse(response *pb.DisconnectResponse) error { 100 if response.Status.String() != "ERROR" { 101 return nil 102 } 103 104 return fmt.Errorf("Application error: %s", response.ErrorMsg) 105 } 106 107 func buildEnv(env *common.SessionEnv) *pb.Env { 108 protoEnv := pb.Env{Url: env.URL, Headers: *env.Headers} 109 if env.ConnectionState != nil { 110 protoEnv.Cstate = *env.ConnectionState 111 } 112 return &protoEnv 113 } 114 115 func buildDisconnectEnv(env *common.SessionEnv) *pb.Env { 116 protoEnv := *buildEnv(env) 117 118 if env.ChannelStates == nil { 119 return &protoEnv 120 } 121 122 states := make(map[string]string) 123 124 for id, state := range *env.ChannelStates { 125 encodedState, _ := json.Marshal(state) 126 127 states[id] = string(encodedState) 128 } 129 130 protoEnv.Istate = states 131 132 return &protoEnv 133 } 134 135 func buildChannelEnv(id string, env *common.SessionEnv) *pb.Env { 136 protoEnv := *buildEnv(env) 137 138 if env.ChannelStates == nil { 139 return &protoEnv 140 } 141 142 if _, ok := (*env.ChannelStates)[id]; ok { 143 protoEnv.Istate = (*env.ChannelStates)[id] 144 } 145 return &protoEnv 146 }