// common.go
package common
import (
"github.com/hprose/hprose-golang/rpc"
"github.com/xxtea/xxtea-go/xxtea"
"github.com/hprose/hprose-golang/io"
"compress/gzip"
"io/ioutil"
"fmt"
)
// 加密过滤器
type XXTEAFilter struct {
Key string
}
// 对输入数据进行处理(来自客户端的加密数据)
func (filter XXTEAFilter) InputFilter(data []byte, context rpc.Context) []byte {
return xxtea.Decrypt(data, []byte(filter.Key));
}
// 对输出数据进行处理(加密后发送到客户端)
func (filter XXTEAFilter) OutputFilter(data []byte, context rpc.Context) []byte {
return xxtea.Encrypt(data, []byte(filter.Key));
}
// 压缩过滤器 ...
type CompressFilter struct{}
func (CompressFilter) InputFilter(data []byte, context rpc.Context) []byte {
b := io.NewByteReader(data)
reader, _ := gzip.NewReader(b)
defer reader.Close()
data, _ = ioutil.ReadAll(reader)
return data
}
func (CompressFilter) OutputFilter(data []byte, context rpc.Context) []byte {
b := &io.ByteWriter{}
writer := gzip.NewWriter(b)
writer.Write(data)
writer.Flush()
return b.Bytes()
}
// SizeFilter ...
type SizeFilter struct {
Message string
}
// InputFilter ...
func (sf SizeFilter) InputFilter(data []byte, context rpc.Context) []byte {
fmt.Println("%v input size: %d\r\n", sf.Message, len(data))
return data
}
// OutputFilter ...
func (sf SizeFilter) OutputFilter(data []byte, context rpc.Context) []byte {
fmt.Println("%v output size: %d\r\n", sf.Message, len(data))
return data
}
//client
package main
import (
"github.com/hprose/hprose-golang/rpc"
"github.com/Sirupsen/logrus"
"os"
"fmt"
"time"
"git.piaoyun.org/piao/hprose_test/common"
)
type SubService struct {
Hello2 func(func(string), string) `name:"hello"` // 相当于其他语言的函数重载
}
type HelloService struct {
SubService
Hello func(func(string, error), string)
Add func(func(int, error), int, int)
Test func(func([]int, error), []int)
}
func init() {
customFormatter := new(logrus.TextFormatter)
customFormatter.FullTimestamp = true // 显示完整时间
customFormatter.TimestampFormat = "2006-01-02 15:04:05" // 时间格式
customFormatter.DisableTimestamp = false // 禁止显示时间
customFormatter.DisableColors = false // 禁止颜色显示
logrus.SetFormatter(customFormatter)
logrus.SetOutput(os.Stdout)
logrus.SetLevel(logrus.DebugLevel)
logrus.Debug("Debug日志")
logrus.Info("Info日志")
logrus.Warn("Warn日志")
logrus.Error("Error日志")
//logrus.Fatal("Fatal日志") //log之后会调用os.Exit(1)
//logrus.Panic("Panic日志") //log之后会panic()
}
// ServerFilter Hprose 过滤接口实现
type ClientFilter struct{
Prompt string
}
// InputFilter 输入过滤
func (ClientFilter) InputFilter(data []byte, context rpc.Context) []byte {
logrus.WithFields(logrus.Fields{
"Filter": "InputFilter",
"DATA": string(data),
"CONTEXT": context,
}).Info("INPUT")
return data
}
// OutputFilter 输出过滤
func (ClientFilter) OutputFilter(data []byte, context rpc.Context) []byte {
logrus.WithFields(logrus.Fields{
"Filter": "OutputFilter",
"DATA": string(data),
"CONTEXT": context,
}).Info("OUTPUT")
return data
}
func main() {
//client := rpc.NewTCPClient("tcp://localhost:1234/")
client := rpc.NewHTTPClient("http://localhost:1234/")
var helloService *HelloService
client.UseService(&helloService)
// 客户端过滤器按照添加顺序执行
//client.AddFilter(XXTEAFilter{"123456790!@#$%^&"});
//client.AddFilter(&ClientFilter{"Client"})
client.AddFilter(
common.SizeFilter{"Non compressed data on client"},
common.CompressFilter{},
common.SizeFilter{"Compressed data on client"},
)
helloService.Hello(func(result string, err error) {
fmt.Println(result, err)
}, "PiaoYun")
helloService.Hello2(func(result string) {
fmt.Println(result)
}, "PiaoYun")
helloService.Add(func(result int, err error) {
fmt.Printf("add result = %d\n", result)
}, 10, 20)
args := make([]int, 100000)
for i := range args {
args[i] = i
}
helloService.Test(func(result []int, err error) {
//fmt.Println("add result = ", result)
}, args)
time.Sleep(time.Second * 2)
}
//server
package main
import (
"github.com/hprose/hprose-golang/rpc"
"reflect"
"github.com/Sirupsen/logrus"
"github.com/astaxie/beego"
"git.piaoyun.org/piao/hprose_test/common"
)
func init() {
log := new(logrus.TextFormatter)
log.FullTimestamp = true // 显示完整时间
log.TimestampFormat = "2006/01/02 - 15:04:05" // 时间格式
log.DisableTimestamp = false // 禁止显示时间
log.DisableColors = false // 禁止颜色显示
log.DisableSorting = false // 禁止字段自动排序
logrus.SetFormatter(log)
//logrus.SetOutput(os.Stdout)
logrus.SetLevel(logrus.DebugLevel)
}
type HelloService struct {
//Hello func(func(string, error), string)
//Add func(func(int, error), int, int)
}
func (HelloService) Hello(name string) string {
logrus.Info("call hello() from client...")
return "Hello " + name + "!"
}
func (HelloService) Add(a, b int) int {
logrus.Info("call add() from client...")
return a + b
}
func (HelloService) Test(data []int) []int {
return data
}
type ServiceEvent struct{}
// 执行函数前调用
func (e *ServiceEvent) OnBeforeInvoke(name string, args []reflect.Value, byref bool, context rpc.Context) {
sContext := context.(*rpc.HTTPContext)
logrus.WithFields(logrus.Fields{
"Event": "OnBeforeInvoke",
"Service": "TestService",
"FuncName": name,
"IP": sContext.Request.RemoteAddr,
"Args": args,
}).Info()
}
// 执行函数后调用
func (e *ServiceEvent) OnAfterInvoke(name string, args []reflect.Value, byref bool, result []reflect.Value, context rpc.Context) {
sContext := context.(*rpc.HTTPContext)
logrus.WithFields(logrus.Fields{
"Event": "OnAfterInvoke",
"Service": "TestService",
"FuncName": name,
"IP": sContext.Request.RemoteAddr,
"Args": args,
"Result": args,
}).Info()
}
// OnSendError 服务端出错时执行
func (e *ServiceEvent) OnSendError(err error, context rpc.Context) {
logrus.Error(err.Error())
}
// 普通过滤器
type ServiceFilter struct{
Prompt string
}
// InputFilter 输入过滤
func (ServiceFilter) InputFilter(data []byte, context rpc.Context) []byte {
logrus.WithFields(logrus.Fields{
"Filter": "InputFilter",
"DATA": string(data),
"CONTEXT": context,
}).Info("INPUT")
return data
}
// OutputFilter 输出过滤
func (ServiceFilter) OutputFilter(data []byte, context rpc.Context) []byte {
logrus.WithFields(logrus.Fields{
"Filter": "OutputFilter",
"DATA": string(data),
"CONTEXT": context,
}).Info("OUTPUT")
return data
}
func main() {
//service := rpc.NewTCPServer("tcp://localhost:1234")
service := rpc.NewHTTPService()
helloService := HelloService{}
//service.AddFunction("hello", helloService.hello)
//service.AddFunction("add", helloService.add)
service.AddAllMethods(&helloService)
service.Event = &ServiceEvent{}
// 服务端过滤器按照添加次序倒序执行
//service.AddFilter(&ServiceFilter{"Service"})
service.AddFilter(
common.SizeFilter{"Non compressed data on server"},
common.CompressFilter{},
common.SizeFilter{"Compressed data on server"},
)
//service.AddFilter(&XXTEAFilter{"123456790!@#$%^&"});
//service.Start()
//return
beego.Handler("/", service)
beego.Run(":1234")
}
发表评论