dubbo.apache.org/dubbo-go/v3@v3.1.1/protocol/jsonrpc/jsonrpc_protocol.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package jsonrpc 19 20 import ( 21 "strings" 22 "sync" 23 "time" 24 ) 25 26 import ( 27 "github.com/dubbogo/gost/log/logger" 28 ) 29 30 import ( 31 "dubbo.apache.org/dubbo-go/v3/common" 32 "dubbo.apache.org/dubbo-go/v3/common/constant" 33 "dubbo.apache.org/dubbo-go/v3/common/extension" 34 "dubbo.apache.org/dubbo-go/v3/config" 35 "dubbo.apache.org/dubbo-go/v3/protocol" 36 ) 37 38 const ( 39 // JSONRPC 40 // module name 41 JSONRPC = "jsonrpc" 42 ) 43 44 func init() { 45 extension.SetProtocol(JSONRPC, GetProtocol) 46 } 47 48 var jsonrpcProtocol *JsonrpcProtocol 49 50 // JsonrpcProtocol is JSON RPC protocol. 51 type JsonrpcProtocol struct { 52 protocol.BaseProtocol 53 serverMap map[string]*Server 54 serverLock sync.Mutex 55 } 56 57 // NewJsonrpcProtocol creates JSON RPC protocol 58 func NewJsonrpcProtocol() *JsonrpcProtocol { 59 return &JsonrpcProtocol{ 60 BaseProtocol: protocol.NewBaseProtocol(), 61 serverMap: make(map[string]*Server), 62 } 63 } 64 65 // Export JSON RPC service for remote invocation 66 func (jp *JsonrpcProtocol) Export(invoker protocol.Invoker) protocol.Exporter { 67 url := invoker.GetURL() 68 serviceKey := strings.TrimPrefix(url.Path, "/") 69 70 exporter := NewJsonrpcExporter(serviceKey, invoker, jp.ExporterMap()) 71 jp.SetExporterMap(serviceKey, exporter) 72 logger.Infof("[JSONRPC protocol] Export service: %s", url.String()) 73 74 // start server 75 jp.openServer(url) 76 77 return exporter 78 } 79 80 // Refer a remote JSON PRC service from registry 81 func (jp *JsonrpcProtocol) Refer(url *common.URL) protocol.Invoker { 82 rtStr := config.GetConsumerConfig().RequestTimeout 83 // the read order of requestTimeout is from url , if nil then from consumer config , if nil then default 3s. requestTimeout can be dynamically updated from config center. 84 requestTimeout := url.GetParamDuration(constant.TimeoutKey, rtStr) 85 // New Json rpc Invoker 86 invoker := NewJsonrpcInvoker(url, NewHTTPClient(&HTTPOptions{ 87 HandshakeTimeout: time.Second, // todo config timeout config.GetConsumerConfig().ConnectTimeout, 88 HTTPTimeout: requestTimeout, 89 })) 90 jp.SetInvokers(invoker) 91 logger.Infof("[JSONRPC Protocol] Refer service: %s", url.String()) 92 return invoker 93 } 94 95 // Destroy will destroy all invoker and exporter, so it only is called once. 96 func (jp *JsonrpcProtocol) Destroy() { 97 logger.Infof("jsonrpcProtocol destroy.") 98 99 jp.BaseProtocol.Destroy() 100 101 // stop server 102 for key, server := range jp.serverMap { 103 delete(jp.serverMap, key) 104 server.Stop() 105 } 106 } 107 108 func (jp *JsonrpcProtocol) openServer(url *common.URL) { 109 _, ok := jp.serverMap[url.Location] 110 if !ok { 111 _, loadOk := jp.ExporterMap().Load(strings.TrimPrefix(url.Path, "/")) 112 if !loadOk { 113 panic("[JsonrpcProtocol]" + url.Key() + "is not existing") 114 } 115 116 jp.serverLock.Lock() 117 _, ok = jp.serverMap[url.Location] 118 if !ok { 119 srv := NewServer() 120 jp.serverMap[url.Location] = srv 121 srv.Start(url) 122 } 123 jp.serverLock.Unlock() 124 } 125 } 126 127 // GetProtocol gets JSON RPC protocol. 128 func GetProtocol() protocol.Protocol { 129 if jsonrpcProtocol == nil { 130 jsonrpcProtocol = NewJsonrpcProtocol() 131 } 132 return jsonrpcProtocol 133 }