This commit is contained in:
2022-03-17 15:55:27 +08:00
commit bd5a9fad97
92 changed files with 13861 additions and 0 deletions

1294
api/comet/grpc/comet.pb.go Normal file

File diff suppressed because it is too large Load Diff

109
api/comet/grpc/comet.proto Normal file
View File

@@ -0,0 +1,109 @@
// protoc -I=. -I=$GOPATH/src --go_out=plugins=grpc:. *.proto
syntax = "proto3";
package im.comet;
option go_package = "gitlab.33.cn/chat/im/api/comet/grpc";
message Proto {
int32 ver = 1;
int32 op = 2;
int32 seq = 3;
int32 ack = 4;
bytes body = 5;
}
enum Op {
Undefined = 0;
Auth = 1;
AuthReply = 2;
Heartbeat = 3;
HeartbeatReply = 4;
Disconnect = 5;
DisconnectReply = 6;
SendMsg = 7;
SendMsgReply = 8; //客户端回复消息已收到
ReceiveMsg = 9;
ReceiveMsgReply = 10;
ProtoReady = 11;
ProtoFinish = 12;
Raw = 13;
SyncMsgReq = 14;
SyncMsgReply = 15;
RePush = 16;
}
// Proto 中 Op 为 OpAuth 时, body 必须可以反序列化为 AuthMsg
message AuthMsg {
string appId = 1;
string token = 2;
bytes ext = 3; // 其它业务方可能需要的信息
}
// Proto 中 Op 为 SyncMsgReply 时, body 必须可以反序列化为 SyncMsg
message SyncMsg {
int64 logId = 1;
}
message Empty{}
message PushMsgReq {
repeated string keys = 1;
int32 protoOp = 2;
Proto proto = 3;
}
message PushMsgReply {
map<string,int32> index = 1;
}
message BroadcastReq{
int32 protoOp = 1;
Proto proto = 2;
}
message BroadcastReply{}
message BroadcastGroupReq {
string groupID = 1;
Proto proto = 2;
}
message BroadcastGroupReply{}
message JoinGroupsReq {
repeated string keys = 1;
repeated string gid = 2;
}
message JoinGroupsReply{}
message LeaveGroupsReq {
repeated string keys = 1;
repeated string gid = 2;
}
message LeaveGroupsReply{}
message DelGroupsReq {
repeated string gid = 1;
}
message DelGroupsReply{}
service Comet {
rpc PushMsg(PushMsgReq) returns (PushMsgReply);
rpc Broadcast(BroadcastReq) returns (BroadcastReply);
rpc BroadcastGroup(BroadcastGroupReq) returns (BroadcastGroupReply);
rpc JoinGroups(JoinGroupsReq) returns (JoinGroupsReply);
rpc LeaveGroups(LeaveGroupsReq) returns (LeaveGroupsReply);
rpc DelGroups(DelGroupsReq) returns (DelGroupsReply);
}

View File

@@ -0,0 +1,281 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package grpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// CometClient is the client API for Comet service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type CometClient interface {
PushMsg(ctx context.Context, in *PushMsgReq, opts ...grpc.CallOption) (*PushMsgReply, error)
Broadcast(ctx context.Context, in *BroadcastReq, opts ...grpc.CallOption) (*BroadcastReply, error)
BroadcastGroup(ctx context.Context, in *BroadcastGroupReq, opts ...grpc.CallOption) (*BroadcastGroupReply, error)
JoinGroups(ctx context.Context, in *JoinGroupsReq, opts ...grpc.CallOption) (*JoinGroupsReply, error)
LeaveGroups(ctx context.Context, in *LeaveGroupsReq, opts ...grpc.CallOption) (*LeaveGroupsReply, error)
DelGroups(ctx context.Context, in *DelGroupsReq, opts ...grpc.CallOption) (*DelGroupsReply, error)
}
type cometClient struct {
cc grpc.ClientConnInterface
}
func NewCometClient(cc grpc.ClientConnInterface) CometClient {
return &cometClient{cc}
}
func (c *cometClient) PushMsg(ctx context.Context, in *PushMsgReq, opts ...grpc.CallOption) (*PushMsgReply, error) {
out := new(PushMsgReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/PushMsg", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *cometClient) Broadcast(ctx context.Context, in *BroadcastReq, opts ...grpc.CallOption) (*BroadcastReply, error) {
out := new(BroadcastReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/Broadcast", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *cometClient) BroadcastGroup(ctx context.Context, in *BroadcastGroupReq, opts ...grpc.CallOption) (*BroadcastGroupReply, error) {
out := new(BroadcastGroupReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/BroadcastGroup", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *cometClient) JoinGroups(ctx context.Context, in *JoinGroupsReq, opts ...grpc.CallOption) (*JoinGroupsReply, error) {
out := new(JoinGroupsReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/JoinGroups", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *cometClient) LeaveGroups(ctx context.Context, in *LeaveGroupsReq, opts ...grpc.CallOption) (*LeaveGroupsReply, error) {
out := new(LeaveGroupsReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/LeaveGroups", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *cometClient) DelGroups(ctx context.Context, in *DelGroupsReq, opts ...grpc.CallOption) (*DelGroupsReply, error) {
out := new(DelGroupsReply)
err := c.cc.Invoke(ctx, "/im.comet.Comet/DelGroups", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// CometServer is the server API for Comet service.
// All implementations must embed UnimplementedCometServer
// for forward compatibility
type CometServer interface {
PushMsg(context.Context, *PushMsgReq) (*PushMsgReply, error)
Broadcast(context.Context, *BroadcastReq) (*BroadcastReply, error)
BroadcastGroup(context.Context, *BroadcastGroupReq) (*BroadcastGroupReply, error)
JoinGroups(context.Context, *JoinGroupsReq) (*JoinGroupsReply, error)
LeaveGroups(context.Context, *LeaveGroupsReq) (*LeaveGroupsReply, error)
DelGroups(context.Context, *DelGroupsReq) (*DelGroupsReply, error)
mustEmbedUnimplementedCometServer()
}
// UnimplementedCometServer must be embedded to have forward compatible implementations.
type UnimplementedCometServer struct {
}
func (UnimplementedCometServer) PushMsg(context.Context, *PushMsgReq) (*PushMsgReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PushMsg not implemented")
}
func (UnimplementedCometServer) Broadcast(context.Context, *BroadcastReq) (*BroadcastReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Broadcast not implemented")
}
func (UnimplementedCometServer) BroadcastGroup(context.Context, *BroadcastGroupReq) (*BroadcastGroupReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method BroadcastGroup not implemented")
}
func (UnimplementedCometServer) JoinGroups(context.Context, *JoinGroupsReq) (*JoinGroupsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method JoinGroups not implemented")
}
func (UnimplementedCometServer) LeaveGroups(context.Context, *LeaveGroupsReq) (*LeaveGroupsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method LeaveGroups not implemented")
}
func (UnimplementedCometServer) DelGroups(context.Context, *DelGroupsReq) (*DelGroupsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method DelGroups not implemented")
}
func (UnimplementedCometServer) mustEmbedUnimplementedCometServer() {}
// UnsafeCometServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to CometServer will
// result in compilation errors.
type UnsafeCometServer interface {
mustEmbedUnimplementedCometServer()
}
func RegisterCometServer(s grpc.ServiceRegistrar, srv CometServer) {
s.RegisterService(&Comet_ServiceDesc, srv)
}
func _Comet_PushMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PushMsgReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).PushMsg(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/PushMsg",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).PushMsg(ctx, req.(*PushMsgReq))
}
return interceptor(ctx, in, info, handler)
}
func _Comet_Broadcast_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BroadcastReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).Broadcast(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/Broadcast",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).Broadcast(ctx, req.(*BroadcastReq))
}
return interceptor(ctx, in, info, handler)
}
func _Comet_BroadcastGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BroadcastGroupReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).BroadcastGroup(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/BroadcastGroup",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).BroadcastGroup(ctx, req.(*BroadcastGroupReq))
}
return interceptor(ctx, in, info, handler)
}
func _Comet_JoinGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(JoinGroupsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).JoinGroups(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/JoinGroups",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).JoinGroups(ctx, req.(*JoinGroupsReq))
}
return interceptor(ctx, in, info, handler)
}
func _Comet_LeaveGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(LeaveGroupsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).LeaveGroups(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/LeaveGroups",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).LeaveGroups(ctx, req.(*LeaveGroupsReq))
}
return interceptor(ctx, in, info, handler)
}
func _Comet_DelGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DelGroupsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CometServer).DelGroups(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.comet.Comet/DelGroups",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CometServer).DelGroups(ctx, req.(*DelGroupsReq))
}
return interceptor(ctx, in, info, handler)
}
// Comet_ServiceDesc is the grpc.ServiceDesc for Comet service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Comet_ServiceDesc = grpc.ServiceDesc{
ServiceName: "im.comet.Comet",
HandlerType: (*CometServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "PushMsg",
Handler: _Comet_PushMsg_Handler,
},
{
MethodName: "Broadcast",
Handler: _Comet_Broadcast_Handler,
},
{
MethodName: "BroadcastGroup",
Handler: _Comet_BroadcastGroup_Handler,
},
{
MethodName: "JoinGroups",
Handler: _Comet_JoinGroups_Handler,
},
{
MethodName: "LeaveGroups",
Handler: _Comet_LeaveGroups_Handler,
},
{
MethodName: "DelGroups",
Handler: _Comet_DelGroups_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "comet.proto",
}

6
api/comet/grpc/create.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
protoc -I. -I$GOPATH/src \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
*.proto

304
api/comet/grpc/protocol.go Normal file
View File

@@ -0,0 +1,304 @@
package grpc
import (
"errors"
"github.com/Terry-Mao/goim/pkg/bufio"
"github.com/Terry-Mao/goim/pkg/bytes"
"github.com/Terry-Mao/goim/pkg/encoding/binary"
"github.com/Terry-Mao/goim/pkg/websocket"
gws "github.com/gorilla/websocket"
)
const (
// MaxBodySize max proto body size
MaxBodySize = int32(1 << 14)
)
const (
// size
_packSize = 4
_headerSize = 2
_verSize = 2
_opSize = 4
_seqSize = 4
_ackSize = 4
_heartSize = 4
_rawHeaderSize = _packSize + _headerSize + _verSize + _opSize + _seqSize + _ackSize
_maxPackSize = MaxBodySize + int32(_rawHeaderSize)
// offset
_packOffset = 0
_headerOffset = _packOffset + _packSize
_verOffset = _headerOffset + _headerSize
_opOffset = _verOffset + _verSize
_seqOffset = _opOffset + _opSize
_ackOffset = _seqOffset + _seqSize
_heartOffset = _ackOffset + _ackSize
)
var (
// ErrProtoPackLen proto packet len error
ErrProtoPackLen = errors.New("default server codec pack length error")
// ErrProtoHeaderLen proto header len error
ErrProtoHeaderLen = errors.New("default server codec header length error")
)
var (
// ProtoReady proto ready
ProtoReady = &Proto{Op: int32(Op_ProtoReady)}
// ProtoFinish proto finish
ProtoFinish = &Proto{Op: int32(Op_ProtoFinish)}
)
// WriteTo write a proto to bytes writer.
func (p *Proto) WriteTo(b *bytes.Writer) {
var (
packLen = _rawHeaderSize + int32(len(p.Body))
buf = b.Peek(_rawHeaderSize)
)
binary.BigEndian.PutInt32(buf[_packOffset:], packLen)
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
if p.Body != nil {
b.Write(p.Body)
}
}
// ReadTCP read a proto from TCP reader.
func (p *Proto) ReadTCP(rr *bufio.Reader) (err error) {
var (
bodyLen int
headerLen int16
packLen int32
buf []byte
)
if buf, err = rr.Pop(_rawHeaderSize); err != nil {
return
}
packLen = binary.BigEndian.Int32(buf[_packOffset:_headerOffset])
headerLen = binary.BigEndian.Int16(buf[_headerOffset:_verOffset])
p.Ver = int32(binary.BigEndian.Int16(buf[_verOffset:_opOffset]))
p.Op = binary.BigEndian.Int32(buf[_opOffset:_seqOffset])
p.Seq = binary.BigEndian.Int32(buf[_seqOffset:_ackOffset])
p.Ack = binary.BigEndian.Int32(buf[_ackOffset:])
if packLen > _maxPackSize {
return ErrProtoPackLen
}
if headerLen != _rawHeaderSize {
return ErrProtoHeaderLen
}
if bodyLen = int(packLen - int32(headerLen)); bodyLen > 0 {
p.Body, err = rr.Pop(bodyLen)
} else {
p.Body = nil
}
return
}
// WriteTCP write a proto to TCP writer.
func (p *Proto) WriteTCP(wr *bufio.Writer) (err error) {
var (
buf []byte
packLen int32
)
if p.Op == int32(Op_Raw) {
// write without buffer, job concact proto into raw buffer
_, err = wr.WriteRaw(p.Body)
return
}
packLen = _rawHeaderSize + int32(len(p.Body))
if buf, err = wr.Peek(_rawHeaderSize); err != nil {
return
}
binary.BigEndian.PutInt32(buf[_packOffset:], packLen)
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
if p.Body != nil {
_, err = wr.Write(p.Body)
}
return
}
// WriteTCPHeart write TCP heartbeat with room online.
func (p *Proto) WriteTCPHeart(wr *bufio.Writer, online int32) (err error) {
var (
buf []byte
packLen int
)
packLen = _rawHeaderSize + _heartSize
if buf, err = wr.Peek(packLen); err != nil {
return
}
// header
binary.BigEndian.PutInt32(buf[_packOffset:], int32(packLen))
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
// body
binary.BigEndian.PutInt32(buf[_heartOffset:], online)
return
}
// ReadWebsocket read a proto from websocket connection.
func (p *Proto) ReadWebsocket(ws *websocket.Conn) (err error) {
var (
bodyLen int
headerLen int16
packLen int32
buf []byte
)
if _, buf, err = ws.ReadMessage(); err != nil {
return
}
if len(buf) < _rawHeaderSize {
return ErrProtoPackLen
}
packLen = binary.BigEndian.Int32(buf[_packOffset:_headerOffset])
headerLen = binary.BigEndian.Int16(buf[_headerOffset:_verOffset])
p.Ver = int32(binary.BigEndian.Int16(buf[_verOffset:_opOffset]))
p.Op = binary.BigEndian.Int32(buf[_opOffset:_seqOffset])
p.Seq = binary.BigEndian.Int32(buf[_seqOffset:_ackOffset])
p.Ack = binary.BigEndian.Int32(buf[_ackOffset:])
if packLen < 0 || packLen > _maxPackSize {
return ErrProtoPackLen
}
if headerLen != _rawHeaderSize {
return ErrProtoHeaderLen
}
if bodyLen = int(packLen - int32(headerLen)); bodyLen > 0 {
p.Body = buf[headerLen:packLen]
} else {
p.Body = nil
}
return
}
// WriteWebsocket write a proto to websocket connection.
func (p *Proto) WriteWebsocket(ws *websocket.Conn) (err error) {
var (
buf []byte
packLen int
)
packLen = _rawHeaderSize + len(p.Body)
if err = ws.WriteHeader(websocket.BinaryMessage, packLen); err != nil {
return
}
if buf, err = ws.Peek(_rawHeaderSize); err != nil {
return
}
binary.BigEndian.PutInt32(buf[_packOffset:], int32(packLen))
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
if p.Body != nil {
err = ws.WriteBody(p.Body)
}
return
}
// WriteWebsocketHeart write websocket heartbeat with room online.
func (p *Proto) WriteWebsocketHeart(wr *websocket.Conn, online int32) (err error) {
var (
buf []byte
packLen int
)
packLen = _rawHeaderSize + _heartSize
// websocket header
if err = wr.WriteHeader(websocket.BinaryMessage, packLen); err != nil {
return
}
if buf, err = wr.Peek(packLen); err != nil {
return
}
// proto header
binary.BigEndian.PutInt32(buf[_packOffset:], int32(packLen))
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
// proto body
binary.BigEndian.PutInt32(buf[_heartOffset:], online)
return
}
// WriteWebsocket write a proto to websocket connection.
func (p *Proto) WriteWebsocket2(ws *gws.Conn) (err error) {
var (
buf []byte
packLen int32
)
wc, err := ws.NextWriter(websocket.BinaryMessage)
if err != nil {
return err
}
wr := bufio.NewWriter(wc)
packLen = _rawHeaderSize + int32(len(p.Body))
if buf, err = wr.Peek(_rawHeaderSize); err != nil {
return
}
binary.BigEndian.PutInt32(buf[_packOffset:], packLen)
binary.BigEndian.PutInt16(buf[_headerOffset:], int16(_rawHeaderSize))
binary.BigEndian.PutInt16(buf[_verOffset:], int16(p.Ver))
binary.BigEndian.PutInt32(buf[_opOffset:], p.Op)
binary.BigEndian.PutInt32(buf[_seqOffset:], p.Seq)
binary.BigEndian.PutInt32(buf[_ackOffset:], p.Ack)
if p.Body != nil {
_, err = wr.Write(p.Body)
}
if err != nil {
return
}
err = wr.Flush()
if err != nil {
return
}
return wc.Close()
}
// ReadWebsocket read a proto from websocket connection.
func (p *Proto) ReadWebsocket2(ws *gws.Conn) (err error) {
var (
bodyLen int
headerLen int16
packLen int32
buf []byte
)
if _, buf, err = ws.ReadMessage(); err != nil {
return
}
if len(buf) < _rawHeaderSize {
return ErrProtoPackLen
}
packLen = binary.BigEndian.Int32(buf[_packOffset:_headerOffset])
headerLen = binary.BigEndian.Int16(buf[_headerOffset:_verOffset])
p.Ver = int32(binary.BigEndian.Int16(buf[_verOffset:_opOffset]))
p.Op = binary.BigEndian.Int32(buf[_opOffset:_seqOffset])
p.Seq = binary.BigEndian.Int32(buf[_seqOffset:_ackOffset])
p.Ack = binary.BigEndian.Int32(buf[_ackOffset:])
if packLen > _maxPackSize {
return ErrProtoPackLen
}
if headerLen != _rawHeaderSize {
return ErrProtoHeaderLen
}
if bodyLen = int(packLen - int32(headerLen)); bodyLen > 0 {
p.Body = buf[headerLen:packLen]
} else {
p.Body = nil
}
return
}

6
api/logic/grpc/create.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
protoc -I. -I$GOPATH/src \
--go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
*.proto

1312
api/logic/grpc/logic.pb.go Normal file

File diff suppressed because it is too large Load Diff

117
api/logic/grpc/logic.proto Normal file
View File

@@ -0,0 +1,117 @@
// protoc -I=. -I=$GOPATH/src --go_out=plugins=grpc:. *.proto
syntax = "proto3";
package im.logic;
option go_package = "gitlab.33.cn/chat/im/api/logic/grpc";
import "gitlab.33.cn/chat/im/api/comet/grpc/comet.proto";
enum Type {
PUSH = 0;
ROOM = 1;
BROADCAST = 2;
}
message ConnectReq {
string server = 1; // 客户端连接的是哪个 comet
im.comet.Proto proto = 3;
}
message ConnectReply {
string key = 1;
string appId = 2;
string mid = 3;
int64 heartbeat = 4;
}
message DisconnectReq {
string key = 1;
string server = 2;
}
message HeartbeatReq {
string key = 1;
string server = 2;
}
message ReceiveReq {
string key = 1;
im.comet.Proto proto = 3;
}
message Reply {
bool isOk = 1;
bytes msg = 2;
}
// logic --> mq
message BizMsg {
string appId = 1;
string fromId = 2;
Type type = 4;
int32 op = 5;
string key = 6;
bytes msg = 7;
}
// biz --> logic
message MidsMsg {
string appId = 1;
repeated string toIds = 2;
Type type = 3;
int32 op = 4;
bytes msg = 5;
}
// biz --> logic
message KeysMsg {
string appId = 1;
repeated string toKeys = 2;
Type type = 3;
int32 op = 4;
bytes msg = 5;
}
// biz --> logic
message GroupMsg {
string appId = 1;
string group = 2;
Type type = 3;
int32 op = 4;
bytes msg = 5;
}
// biz --> logic
message GroupsKey {
string appId = 1;
repeated string keys = 2;
repeated string gid = 3;
}
// biz --> logic
message GroupsMid {
string appId = 1;
repeated string mids = 2;
repeated string gid = 3;
}
// biz --> logic
message DelGroupsReq {
string appId = 1;
repeated string gid = 2;
}
service Logic {
rpc Connect(ConnectReq) returns (ConnectReply); //comet
rpc Disconnect(DisconnectReq) returns (Reply); //comet
rpc Heartbeat(HeartbeatReq) returns (Reply); //comet
rpc Receive(ReceiveReq) returns (Reply); //comet
rpc PushByMids(MidsMsg) returns (Reply); //biz
rpc PushByKeys(KeysMsg) returns (Reply); //biz
rpc PushGroup(GroupMsg) returns (Reply); //biz
rpc JoinGroupsByKeys(GroupsKey) returns (Reply); //biz
rpc JoinGroupsByMids(GroupsMid) returns (Reply); //biz
rpc LeaveGroupsByKeys(GroupsKey) returns (Reply); //biz
rpc LeaveGroupsByMids(GroupsMid) returns (Reply); //biz
rpc DelGroups(DelGroupsReq) returns (Reply); //biz
}

View File

@@ -0,0 +1,497 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package grpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// LogicClient is the client API for Logic service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type LogicClient interface {
Connect(ctx context.Context, in *ConnectReq, opts ...grpc.CallOption) (*ConnectReply, error)
Disconnect(ctx context.Context, in *DisconnectReq, opts ...grpc.CallOption) (*Reply, error)
Heartbeat(ctx context.Context, in *HeartbeatReq, opts ...grpc.CallOption) (*Reply, error)
Receive(ctx context.Context, in *ReceiveReq, opts ...grpc.CallOption) (*Reply, error)
PushByMids(ctx context.Context, in *MidsMsg, opts ...grpc.CallOption) (*Reply, error)
PushByKeys(ctx context.Context, in *KeysMsg, opts ...grpc.CallOption) (*Reply, error)
PushGroup(ctx context.Context, in *GroupMsg, opts ...grpc.CallOption) (*Reply, error)
JoinGroupsByKeys(ctx context.Context, in *GroupsKey, opts ...grpc.CallOption) (*Reply, error)
JoinGroupsByMids(ctx context.Context, in *GroupsMid, opts ...grpc.CallOption) (*Reply, error)
LeaveGroupsByKeys(ctx context.Context, in *GroupsKey, opts ...grpc.CallOption) (*Reply, error)
LeaveGroupsByMids(ctx context.Context, in *GroupsMid, opts ...grpc.CallOption) (*Reply, error)
DelGroups(ctx context.Context, in *DelGroupsReq, opts ...grpc.CallOption) (*Reply, error)
}
type logicClient struct {
cc grpc.ClientConnInterface
}
func NewLogicClient(cc grpc.ClientConnInterface) LogicClient {
return &logicClient{cc}
}
func (c *logicClient) Connect(ctx context.Context, in *ConnectReq, opts ...grpc.CallOption) (*ConnectReply, error) {
out := new(ConnectReply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/Connect", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) Disconnect(ctx context.Context, in *DisconnectReq, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/Disconnect", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) Heartbeat(ctx context.Context, in *HeartbeatReq, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/Heartbeat", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) Receive(ctx context.Context, in *ReceiveReq, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/Receive", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) PushByMids(ctx context.Context, in *MidsMsg, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/PushByMids", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) PushByKeys(ctx context.Context, in *KeysMsg, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/PushByKeys", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) PushGroup(ctx context.Context, in *GroupMsg, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/PushGroup", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) JoinGroupsByKeys(ctx context.Context, in *GroupsKey, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/JoinGroupsByKeys", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) JoinGroupsByMids(ctx context.Context, in *GroupsMid, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/JoinGroupsByMids", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) LeaveGroupsByKeys(ctx context.Context, in *GroupsKey, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/LeaveGroupsByKeys", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) LeaveGroupsByMids(ctx context.Context, in *GroupsMid, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/LeaveGroupsByMids", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *logicClient) DelGroups(ctx context.Context, in *DelGroupsReq, opts ...grpc.CallOption) (*Reply, error) {
out := new(Reply)
err := c.cc.Invoke(ctx, "/im.logic.Logic/DelGroups", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// LogicServer is the server API for Logic service.
// All implementations must embed UnimplementedLogicServer
// for forward compatibility
type LogicServer interface {
Connect(context.Context, *ConnectReq) (*ConnectReply, error)
Disconnect(context.Context, *DisconnectReq) (*Reply, error)
Heartbeat(context.Context, *HeartbeatReq) (*Reply, error)
Receive(context.Context, *ReceiveReq) (*Reply, error)
PushByMids(context.Context, *MidsMsg) (*Reply, error)
PushByKeys(context.Context, *KeysMsg) (*Reply, error)
PushGroup(context.Context, *GroupMsg) (*Reply, error)
JoinGroupsByKeys(context.Context, *GroupsKey) (*Reply, error)
JoinGroupsByMids(context.Context, *GroupsMid) (*Reply, error)
LeaveGroupsByKeys(context.Context, *GroupsKey) (*Reply, error)
LeaveGroupsByMids(context.Context, *GroupsMid) (*Reply, error)
DelGroups(context.Context, *DelGroupsReq) (*Reply, error)
mustEmbedUnimplementedLogicServer()
}
// UnimplementedLogicServer must be embedded to have forward compatible implementations.
type UnimplementedLogicServer struct {
}
func (UnimplementedLogicServer) Connect(context.Context, *ConnectReq) (*ConnectReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Connect not implemented")
}
func (UnimplementedLogicServer) Disconnect(context.Context, *DisconnectReq) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Disconnect not implemented")
}
func (UnimplementedLogicServer) Heartbeat(context.Context, *HeartbeatReq) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Heartbeat not implemented")
}
func (UnimplementedLogicServer) Receive(context.Context, *ReceiveReq) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Receive not implemented")
}
func (UnimplementedLogicServer) PushByMids(context.Context, *MidsMsg) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PushByMids not implemented")
}
func (UnimplementedLogicServer) PushByKeys(context.Context, *KeysMsg) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PushByKeys not implemented")
}
func (UnimplementedLogicServer) PushGroup(context.Context, *GroupMsg) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PushGroup not implemented")
}
func (UnimplementedLogicServer) JoinGroupsByKeys(context.Context, *GroupsKey) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method JoinGroupsByKeys not implemented")
}
func (UnimplementedLogicServer) JoinGroupsByMids(context.Context, *GroupsMid) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method JoinGroupsByMids not implemented")
}
func (UnimplementedLogicServer) LeaveGroupsByKeys(context.Context, *GroupsKey) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method LeaveGroupsByKeys not implemented")
}
func (UnimplementedLogicServer) LeaveGroupsByMids(context.Context, *GroupsMid) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method LeaveGroupsByMids not implemented")
}
func (UnimplementedLogicServer) DelGroups(context.Context, *DelGroupsReq) (*Reply, error) {
return nil, status.Errorf(codes.Unimplemented, "method DelGroups not implemented")
}
func (UnimplementedLogicServer) mustEmbedUnimplementedLogicServer() {}
// UnsafeLogicServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to LogicServer will
// result in compilation errors.
type UnsafeLogicServer interface {
mustEmbedUnimplementedLogicServer()
}
func RegisterLogicServer(s grpc.ServiceRegistrar, srv LogicServer) {
s.RegisterService(&Logic_ServiceDesc, srv)
}
func _Logic_Connect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ConnectReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).Connect(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/Connect",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).Connect(ctx, req.(*ConnectReq))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_Disconnect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DisconnectReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).Disconnect(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/Disconnect",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).Disconnect(ctx, req.(*DisconnectReq))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_Heartbeat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HeartbeatReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).Heartbeat(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/Heartbeat",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).Heartbeat(ctx, req.(*HeartbeatReq))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_Receive_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReceiveReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).Receive(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/Receive",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).Receive(ctx, req.(*ReceiveReq))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_PushByMids_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MidsMsg)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).PushByMids(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/PushByMids",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).PushByMids(ctx, req.(*MidsMsg))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_PushByKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(KeysMsg)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).PushByKeys(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/PushByKeys",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).PushByKeys(ctx, req.(*KeysMsg))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_PushGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GroupMsg)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).PushGroup(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/PushGroup",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).PushGroup(ctx, req.(*GroupMsg))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_JoinGroupsByKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GroupsKey)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).JoinGroupsByKeys(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/JoinGroupsByKeys",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).JoinGroupsByKeys(ctx, req.(*GroupsKey))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_JoinGroupsByMids_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GroupsMid)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).JoinGroupsByMids(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/JoinGroupsByMids",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).JoinGroupsByMids(ctx, req.(*GroupsMid))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_LeaveGroupsByKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GroupsKey)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).LeaveGroupsByKeys(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/LeaveGroupsByKeys",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).LeaveGroupsByKeys(ctx, req.(*GroupsKey))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_LeaveGroupsByMids_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GroupsMid)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).LeaveGroupsByMids(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/LeaveGroupsByMids",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).LeaveGroupsByMids(ctx, req.(*GroupsMid))
}
return interceptor(ctx, in, info, handler)
}
func _Logic_DelGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DelGroupsReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(LogicServer).DelGroups(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/im.logic.Logic/DelGroups",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(LogicServer).DelGroups(ctx, req.(*DelGroupsReq))
}
return interceptor(ctx, in, info, handler)
}
// Logic_ServiceDesc is the grpc.ServiceDesc for Logic service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Logic_ServiceDesc = grpc.ServiceDesc{
ServiceName: "im.logic.Logic",
HandlerType: (*LogicServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Connect",
Handler: _Logic_Connect_Handler,
},
{
MethodName: "Disconnect",
Handler: _Logic_Disconnect_Handler,
},
{
MethodName: "Heartbeat",
Handler: _Logic_Heartbeat_Handler,
},
{
MethodName: "Receive",
Handler: _Logic_Receive_Handler,
},
{
MethodName: "PushByMids",
Handler: _Logic_PushByMids_Handler,
},
{
MethodName: "PushByKeys",
Handler: _Logic_PushByKeys_Handler,
},
{
MethodName: "PushGroup",
Handler: _Logic_PushGroup_Handler,
},
{
MethodName: "JoinGroupsByKeys",
Handler: _Logic_JoinGroupsByKeys_Handler,
},
{
MethodName: "JoinGroupsByMids",
Handler: _Logic_JoinGroupsByMids_Handler,
},
{
MethodName: "LeaveGroupsByKeys",
Handler: _Logic_LeaveGroupsByKeys_Handler,
},
{
MethodName: "LeaveGroupsByMids",
Handler: _Logic_LeaveGroupsByMids_Handler,
},
{
MethodName: "DelGroups",
Handler: _Logic_DelGroups_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "logic.proto",
}