Skip to content

Commit

Permalink
Support WebRTC communication
Browse files Browse the repository at this point in the history
Signed-off-by: billfort <[email protected]>
  • Loading branch information
billfort authored and yilunzhang committed Apr 27, 2024
1 parent c9773e8 commit 6edd104
Show file tree
Hide file tree
Showing 17 changed files with 945 additions and 262 deletions.
65 changes: 62 additions & 3 deletions api/common/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import (
"encoding/json"
"fmt"
"net"
"net/url"
"strings"
"time"

"github.com/nknorg/nkn/v2/api/common/errcode"
"github.com/nknorg/nkn/v2/api/httpjson/client"
"github.com/nknorg/nkn/v2/api/webrtc"
"github.com/nknorg/nkn/v2/block"
"github.com/nknorg/nkn/v2/chain"
"github.com/nknorg/nkn/v2/common"
Expand Down Expand Up @@ -412,12 +416,13 @@ func getVersion(s Serverer, params map[string]interface{}, ctx context.Context)
return respPacking(errcode.SUCCESS, config.Version)
}

func NodeInfo(wsAddr, rpcAddr string, pubkey, id []byte) map[string]string {
func NodeInfo(wsAddr, rpcAddr string, pubkey, id []byte, sdp string) map[string]string {
nodeInfo := make(map[string]string)
nodeInfo["addr"] = wsAddr
nodeInfo["rpcAddr"] = rpcAddr
nodeInfo["pubkey"] = hex.EncodeToString(pubkey)
nodeInfo["id"] = hex.EncodeToString(id)
nodeInfo["sdp"] = sdp
return nodeInfo
}

Expand All @@ -444,7 +449,7 @@ func getWsAddr(s Serverer, params map[string]interface{}, ctx context.Context) m
return respPacking(errcode.INTERNAL_ERROR, err.Error())
}

return respPacking(errcode.SUCCESS, NodeInfo(wsAddr, rpcAddr, pubkey, id))
return respPacking(errcode.SUCCESS, NodeInfo(wsAddr, rpcAddr, pubkey, id, ""))
}

func getWssAddr(s Serverer, params map[string]interface{}, ctx context.Context) map[string]interface{} {
Expand All @@ -467,7 +472,7 @@ func getWssAddr(s Serverer, params map[string]interface{}, ctx context.Context)
return respPacking(errcode.INTERNAL_ERROR, err.Error())
}

return respPacking(errcode.SUCCESS, NodeInfo(wsAddr, rpcAddr, pubkey, id))
return respPacking(errcode.SUCCESS, NodeInfo(wsAddr, rpcAddr, pubkey, id, ""))
}

// getBalanceByAddr gets balance by address
Expand Down Expand Up @@ -953,6 +958,59 @@ func findSuccessorAddr(s Serverer, params map[string]interface{}, ctx context.Co
return respPacking(errcode.SUCCESS, addrs[0])
}

// getPeerAddr get a node address
// params: {"address":<address>}
// return: {"resultOrData":<result>|<error data>, "error":<errcode>}
func getPeerAddr(s Serverer, params map[string]interface{}, ctx context.Context) map[string]interface{} {
if len(params) < 1 {
return RespPacking("length of params is less than 1", errcode.INVALID_PARAMS)
}

str, ok := params["address"].(string)
if !ok {
return RespPacking("address should be a string", errcode.INTERNAL_ERROR)
}

clientID, _, _, err := address.ParseClientAddress(str)
if err != nil {
return RespPacking(err.Error(), errcode.INTERNAL_ERROR)
}

wsAddr, rpcAddr, pubkey, id, err := s.GetNetNode().FindWsAddr(clientID)
if err != nil {
return RespPacking(err.Error(), errcode.INTERNAL_ERROR)
}

n := s.GetNetNode()
if n == nil {
return nil
}

if n.GetWsAddr() == wsAddr {
offer := params["offer"].(string)
peer := webrtc.NewPeer(config.Parameters.StunList)

err = peer.Answer(offer)
if err != nil {
return RespPacking(err.Error(), errcode.INTERNAL_ERROR)
}
select {
case answer := <-peer.OnSdp:
return RespPacking(NodeInfo(wsAddr, rpcAddr, pubkey, id, answer), errcode.SUCCESS)
case <-time.After(10 * time.Second):
return RespPacking(fmt.Errorf("webrtc, wait for sdp time out"), errcode.INTERNAL_ERROR)
}
}

reqAddr := (&url.URL{Scheme: "http", Host: rpcAddr}).String()
wsAddr, rpcAddr, pubkey, id, sdp, err := client.GetPeerAddr(reqAddr, params)
if err != nil {
return RespPacking(err.Error(), errcode.INTERNAL_ERROR)
}

return RespPacking(NodeInfo(wsAddr, rpcAddr, pubkey, id, sdp), errcode.SUCCESS)
}

var InitialAPIHandlers = map[string]APIHandler{
"getlatestblockhash": {Handler: getLatestBlockHash, AccessCtrl: BIT_JSONRPC},
"getblock": {Handler: getBlock, AccessCtrl: BIT_JSONRPC},
Expand Down Expand Up @@ -983,4 +1041,5 @@ var InitialAPIHandlers = map[string]APIHandler{
"findsuccessoraddr": {Handler: findSuccessorAddr, AccessCtrl: BIT_JSONRPC},
"findsuccessoraddrs": {Handler: findSuccessorAddrs, AccessCtrl: BIT_JSONRPC},
"getregistrant": {Handler: getRegistrant, AccessCtrl: BIT_JSONRPC},
"getpeeraddr": {Handler: getPeerAddr, AccessCtrl: BIT_JSONRPC},
}
1 change: 1 addition & 0 deletions api/httpjson/RPCserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func (s *RPCServer) Handle(w http.ResponseWriter, r *http.Request) {
}
method, ok = request["method"].(string)
if !ok {
log.Warning("RPC Server - No function to call for ", method)
code = errcode.INVALID_METHOD
}
if request["params"] != nil {
Expand Down
33 changes: 33 additions & 0 deletions api/httpjson/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,36 @@ func GetNonceByAddr(remote, addr string, txPool bool) (uint64, uint32, error) {

return nonce, ret.Result.CurrentHeight, nil
}

func GetPeerAddr(remote string, params map[string]interface{}) (string, string, []byte, []byte, string, error) {
fmt.Println("......GetPeerAddr, remote: ", remote)
resp, err := Call(remote, "getpeeraddr", 0, params)
if err != nil {
return "", "", nil, nil, "", err
}

// log.Infof("Node-to-Node GetPeerAddr got resp: %v from %s\n", string(resp), remote)

var ret struct {
Result struct {
Addr string `json:"addr"`
RpcAddr string `json:"rpcAddr"`
Pubkey []byte `json:"pubkey"`
Id []byte `json:"id"`
Sdp string `json:"sdp"`
} `json:"result"`
Err map[string]interface{} `json:"error"`
}

if err := json.Unmarshal(resp, &ret); err != nil {
log.Error("Node-to-Node GetPeerAddr json.Unmarshal error: ", err)
return "", "", nil, nil, "", err
}
if len(ret.Err) != 0 { // resp.error NOT empty
log.Error("Node-to-Node GetPeerAddr ret.Err: ", ret.Err)
return "", "", nil, nil, "", fmt.Errorf("GetPeerAddr(%s) resp error: %v", remote, string(resp))
}

fmt.Printf("......GetPeerAddr got result: %+v\n", ret.Result)
return ret.Result.Addr, ret.Result.RpcAddr, ret.Result.Pubkey, ret.Result.Id, ret.Result.Sdp, nil
}
Loading

0 comments on commit 6edd104

Please sign in to comment.