Giter Site home page Giter Site logo

Comments (11)

fengqi avatar fengqi commented on August 27, 2024 1

自定义标识位我之前看漏了,我用了比较粗暴的方式解决,暂时能满足功能,我看看再优化下

package middleware

import (
	"encoding/binary"
	"github.com/lesismal/arpc"
	"github.com/vmihailenco/msgpack"
)

type ValuesAppend struct{}

// values 预设长度
const valuesFlagLen = 4

var _ arpc.MessageCoder = &ValuesAppend{}

// NewValuesAppend returns the MsgPack coding middleware.
func NewValuesAppend() *ValuesAppend {
	return new(ValuesAppend)
}

func (mp *ValuesAppend) Encode(client *arpc.Client, msg *arpc.Message) *arpc.Message {
	data, err := msgpack.Marshal(msg.Values())
	if err != nil {
		return msg
	}

	valueLen := len(data)
	bodyLen := msg.BodyLen()

	// 追加 values
	msg.Buffer = append(msg.Buffer, data...)

	// 追加 valuesLen 占位符,并写入实际数据
	msg.Buffer = append(msg.Buffer, make([]byte, valuesFlagLen)...)
	binary.LittleEndian.PutUint32(msg.Buffer[arpc.HeadLen+bodyLen+valueLen:], uint32(valueLen))

	msg.SetBodyLen(len(msg.Buffer) - arpc.HeadLen)

	return msg
}

func (mp *ValuesAppend) Decode(client *arpc.Client, msg *arpc.Message) *arpc.Message {
	// head + body(method + data) + values + valuesLen
	bufferLen := len(msg.Buffer)

	// 最后几位记录values的长度
	valueLen := int(binary.LittleEndian.Uint32(msg.Buffer[bufferLen-valuesFlagLen:]))

	// 计算真实的body的长度,body包括method
	realBodyLen := msg.BodyLen() - valueLen - valuesFlagLen + arpc.HeadLen

	// 反序列化values到map,目前只有msgpack能识别 map[interface{}]interface{}
	data := msg.Buffer[realBodyLen : bufferLen-valuesFlagLen]
	var values map[interface{}]interface{}
	err := msgpack.Unmarshal(data, &values)
	if err != nil {
		return msg
	}

	for k, v := range values {
		msg.Set(k, v)
	}

	msg.Buffer = msg.Buffer[:realBodyLen]
	msg.SetBodyLen(realBodyLen)

	return msg
}

from arpc.

lesismal avatar lesismal commented on August 27, 2024

这主要是为用户留出扩展空间的,用户可以自己定义编解码中间件,比如tracing的中间件扩展和示例:
https://github.com/lesismal/arpc/tree/master/examples/middleware/coder/tracing

因为对于arpc本身,用户的value的格式未知,所以arpc自己难做这种内置的定制,具体的实现应由用户完成。

中间件的好处是业务逻辑解耦,但消耗多一点性能。

如果不想定制编解码中间件,最简单的方式就是在业务需要的地方把这些value带在Call的结构体上

from arpc.

wksw avatar wksw commented on August 27, 2024

https://github.com/lesismal/arpc/blob/master/extension/middleware/coder/msgpack/msgpack.go
我需要的应该是这个, 这个能满足需求

from arpc.

github-actions avatar github-actions commented on August 27, 2024

This issue is stale because it has been open for 30 days with no activity.

from arpc.

fengqi avatar fengqi commented on August 27, 2024

使用 msgpack 这个 中间件可以实现 values 的传递,但是等于是在内置的 jsoncodec 编码过一次的基础上再次编码一次

如果newMessage 里 ValueToBytes 这一步把 values 也传入,默认的实现可以不处理 values,但是自定义的就可以处理,这样起码不用再coder里再去编码一次

只需要把 Codec 这个接口的 Marshal和Unmarshal加个参数,或者新开两个 withValues方法,加上noop默认无实现,是不是也可以做的向下兼容

from arpc.

fengqi avatar fengqi commented on August 27, 2024

使用 msgpack 这个 中间件可以实现 values 的传递,但是等于是在内置的 jsoncodec 编码过一次的基础上再次编码一次

如果newMessage 里 ValueToBytes 这一步把 values 也传入,默认的实现可以不处理 values,但是自定义的就可以处理,这样起码不用再coder里再去编码一次

只需要把 Codec 这个接口的 Marshal和Unmarshal加个参数,或者新开两个 withValues方法,加上noop默认无实现,是不是也可以做的向下兼容

好行不太行,应该values多出来的bodyLen传不出来,额 那现在的value和body分开处理局限有点大啊

from arpc.

lesismal avatar lesismal commented on August 27, 2024

好行不太行,应该values多出来的bodyLen传不出来,额 那现在的value和body分开处理局限有点大啊

所以我给的建议是上面提到的tracing中间件的例子,可以参考这个例子用二进制来做。实际上把你需要的值打包到msg、追加到包体尾部或者取出解析的逻辑的编解码中间件已经封装好了:
https://github.com/lesismal/arpc/blob/5d0e0e9b1b7ed540a64efbeaea1fa5b0e53f99fa/extension/middleware/coder/appender.go

你只需要实现ValueToBytes BytesToValue方法作为Appender的参数,然后创建Appender:
https://github.com/lesismal/arpc/blob/master/extension/middleware/coder/tracing/tracer.go#L85

并使用它作为编解码中间件就可以了(这里的Tracer是切面形式的has a Appender,Appender实现了Encode/Decode):
https://github.com/lesismal/arpc/blob/master/examples/middleware/coder/tracing/server/server.go#L41

from arpc.

lesismal avatar lesismal commented on August 27, 2024

消息头的第 HeaderIndexFlag index 字节是保留字节,主要是留给用户自行扩展时做标记位用的,注意,如果你使用了多个中间件都需要设置标记位,不要使用相同的标记位index,免得冲突了。如果编解码中间件都是自己团队的功能,通常就一个标记位、都在一个编解码中间件中实现功能性价比最高。保留字节在这里:
https://github.com/lesismal/arpc/blob/master/proto.go#L197

from arpc.

lesismal avatar lesismal commented on August 27, 2024

http因为自带了header的编解码,所以用户添加header就可以、不需要自己操心编解码。而rpc为了性能是固定定义的pb之类的,如果是非固定定义比如json格式,那你只需要把tracing相关的字段作为json公共的字段就可以了,比如用map,或者你们的json结构体都继承/has a/切面一个tracing相关的结构体,这种就不需要编解码中间件了,性价比也是最高的。

当然,即使用pb,也可以所有结构体都has a公共的tracign字段,但这是业务侵入的,可能涉及旧业务、兼容之类的问题,要看你们自己的取舍了。

from arpc.

github-actions avatar github-actions commented on August 27, 2024

This issue is stale because it has been open for 30 days with no activity.

from arpc.

github-actions avatar github-actions commented on August 27, 2024

This issue was closed because it has been inactive for 14 days since being marked as stale.

from arpc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.