github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/serviceCmd/rpc_AUTO.go (about)

     1  package serviceCmd
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"github.com/bronze1man/kmg/kmgCrypto"
     9  	"github.com/bronze1man/kmg/kmgLog"
    10  	"github.com/bronze1man/kmg/kmgNet/kmgHttp"
    11  	"net/http"
    12  )
    13  
    14  type Client_ServiceRpc struct {
    15  	RemoteUrl string // http://kmg.org:1234/
    16  	Psk       *[32]byte
    17  }
    18  
    19  //server
    20  func ListenAndServe_ServiceRpc(addr string, obj *ServiceRpc, psk *[32]byte) (closer func() error) {
    21  	s := NewServer_ServiceRpc(obj, psk)
    22  	return kmgHttp.MustGoHttpAsyncListenAndServeWithCloser(addr, s)
    23  }
    24  func NewServer_ServiceRpc(obj *ServiceRpc, psk *[32]byte) http.Handler {
    25  	return &generateServer_ServiceRpc{
    26  		obj: obj,
    27  		psk: psk,
    28  	}
    29  }
    30  func NewClient_ServiceRpc(RemoteUrl string, Psk *[32]byte) *Client_ServiceRpc {
    31  	return &Client_ServiceRpc{RemoteUrl: RemoteUrl, Psk: Psk}
    32  }
    33  
    34  type generateServer_ServiceRpc struct {
    35  	obj *ServiceRpc
    36  	psk *[32]byte
    37  }
    38  
    39  // http-json-api v1
    40  // 1.数据传输使用psk加密,明文不泄漏信息
    41  // 2.使用json序列化信息
    42  // 3.只有部分api
    43  func (s *generateServer_ServiceRpc) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    44  	b1, err := kmgHttp.RequestReadAllBody(req)
    45  	if err != nil {
    46  		http.Error(w, "error 1", 400)
    47  		kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req))
    48  		return
    49  	}
    50  	if s.psk != nil {
    51  		//解密
    52  		b1, err = kmgCrypto.CompressAndEncryptBytesDecodeV2(s.psk, b1)
    53  		if err != nil {
    54  			http.Error(w, "error 2", 400)
    55  			kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req))
    56  			return
    57  		}
    58  	}
    59  	outBuf, err := s.handleApiV1(b1, w, req)
    60  	if err != nil {
    61  		kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req))
    62  		outBuf = append([]byte{1}, err.Error()...) // error
    63  	} else {
    64  		outBuf = append([]byte{2}, outBuf...) // success
    65  	}
    66  	if s.psk != nil {
    67  		//加密
    68  		outBuf = kmgCrypto.CompressAndEncryptBytesEncodeV2(s.psk, outBuf)
    69  	}
    70  	w.WriteHeader(200)
    71  	w.Header().Set("Content-type", "image/jpeg")
    72  	w.Write(outBuf)
    73  }
    74  func (c *Client_ServiceRpc) sendRequest(apiName string, inData interface{}, outData interface{}) (err error) {
    75  	inDataByte, err := json.Marshal(inData)
    76  	if err != nil {
    77  		return
    78  	}
    79  	if len(apiName) > 255 {
    80  		return errors.New("len(apiName)>255")
    81  	}
    82  	inByte := []byte{byte(len(apiName))}
    83  	inByte = append(inByte, []byte(apiName)...)
    84  	inByte = append(inByte, inDataByte...)
    85  	if c.Psk != nil {
    86  		inByte = kmgCrypto.CompressAndEncryptBytesEncodeV2(c.Psk, inByte)
    87  	}
    88  	resp, err := http.Post(c.RemoteUrl, "image/jpeg", bytes.NewBuffer(inByte))
    89  	if err != nil {
    90  		return
    91  	}
    92  	outByte, err := kmgHttp.ResponseReadAllBody(resp)
    93  	if err != nil {
    94  		return
    95  	}
    96  	if c.Psk != nil {
    97  		outByte, err = kmgCrypto.CompressAndEncryptBytesDecodeV2(c.Psk, outByte)
    98  		if err != nil {
    99  			return
   100  		}
   101  	}
   102  	if len(outByte) == 0 {
   103  		return errors.New("len(outByte)==0")
   104  	}
   105  	switch outByte[0] {
   106  	case 1: //error
   107  		return errors.New(string(outByte[1:]))
   108  	case 2: //success
   109  		return json.Unmarshal(outByte[1:], outData)
   110  	default:
   111  		return fmt.Errorf("httpjsonApi protocol error 1 %d", outByte[0])
   112  	}
   113  }
   114  func (s *generateServer_ServiceRpc) handleApiV1(inBuf []byte, _httpW http.ResponseWriter, _httpReq *http.Request) (outBuf []byte, err error) {
   115  	//从此处开始协议正确了,换一种返回方式
   116  	// 1 byte api name len apiNameLen
   117  	// apiNameLen byte api name
   118  	// xx byte json encode of request as struct.
   119  	if len(inBuf) < 2 {
   120  		return nil, fmt.Errorf("len(b1)<2")
   121  	}
   122  	nameLength := inBuf[0]
   123  	if len(inBuf) < int(nameLength)+1 {
   124  		return nil, fmt.Errorf("len(b1)<nameLength+1")
   125  	}
   126  	name := string(inBuf[1 : int(nameLength)+1])
   127  	b2 := inBuf[nameLength+1:]
   128  	switch name {
   129  	case "Send":
   130  		var Err error
   131  		reqData := &struct {
   132  			Status StartStatus
   133  		}{}
   134  		Err = json.Unmarshal(b2, reqData)
   135  		if Err != nil {
   136  			return nil, Err
   137  		}
   138  		s.obj.Send(reqData.Status)
   139  		return json.Marshal(struct {
   140  		}{})
   141  	}
   142  	return nil, fmt.Errorf("api %s not found", name)
   143  }
   144  func (c *Client_ServiceRpc) Send(Status StartStatus) (Err error) {
   145  	reqData := &struct {
   146  		Status StartStatus
   147  	}{
   148  		Status: Status,
   149  	}
   150  	respData := &struct {
   151  	}{}
   152  	Err = c.sendRequest("Send", reqData, &respData)
   153  	return Err
   154  }
   155  
   156  var gClient_ServiceRpc *Client_ServiceRpc
   157  
   158  // 全局函数,请先设置客户端的地址,再获取全局客户端,此处不能并发调用
   159  func SetClient_ServiceRpcConfig(RemoteAddr string, Psk *[32]byte) {
   160  	gClient_ServiceRpc = NewClient_ServiceRpc(RemoteAddr, Psk)
   161  }
   162  func GetClient_ServiceRpc() *Client_ServiceRpc {
   163  	return gClient_ServiceRpc
   164  }