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

126
comet/comet.go Normal file
View File

@@ -0,0 +1,126 @@
package comet
import (
"context"
"fmt"
"math/rand"
"net"
"time"
"github.com/Terry-Mao/goim/pkg/ip"
"github.com/zhenjl/cityhash"
"gitlab.33.cn/chat/im-pkg/trace"
comet "gitlab.33.cn/chat/im/api/comet/grpc"
logic "gitlab.33.cn/chat/im/api/logic/grpc"
"gitlab.33.cn/chat/im/comet/conf"
"gitlab.33.cn/chat/im/common"
"gitlab.33.cn/chat/im/naming"
"google.golang.org/grpc"
"google.golang.org/grpc/resolver"
)
// Comet is comet server.
type Comet struct {
c *conf.Config
round *Round
buckets []*Bucket // subkey bucket
bucketIdx uint32
serverID string
logicRPCClient logic.LogicClient
}
// NewServer returns a new Server.
func New(c *conf.Config) *Comet {
s := &Comet{
c: c,
round: NewRound(c),
logicRPCClient: newLogicClient(c),
}
// init bucket
s.buckets = make([]*Bucket, c.Bucket.Size)
s.bucketIdx = uint32(c.Bucket.Size)
for i := 0; i < c.Bucket.Size; i++ {
s.buckets[i] = NewBucket(c.Bucket)
}
addr := ip.InternalIP()
_, port, _ := net.SplitHostPort(c.RPCServer.Addr)
s.serverID = "grpc://" + addr + ":" + port
return s
}
func newLogicClient(c *conf.Config) logic.LogicClient {
rb := naming.NewResolver(c.Reg.RegAddrs, c.LogicRPCClient.Schema)
resolver.Register(rb)
addr := fmt.Sprintf("%s:///%s", c.LogicRPCClient.Schema, c.LogicRPCClient.SrvName) // "schema://[authority]/service"
fmt.Println("rpc client call addr:", addr)
conn, err := common.NewGRPCConn(addr, time.Duration(c.LogicRPCClient.Dial), grpc.WithUnaryInterceptor(trace.OpentracingClientInterceptor))
if err != nil {
panic(err)
}
return logic.NewLogicClient(conn)
}
// Buckets return all buckets.
func (s *Comet) Buckets() []*Bucket {
return s.buckets
}
// Bucket get the bucket by subkey.
func (s *Comet) Bucket(subKey string) *Bucket {
idx := cityhash.CityHash32([]byte(subKey), uint32(len(subKey))) % s.bucketIdx
return s.buckets[idx]
}
// RandServerHearbeat rand server heartbeat.
func (s *Comet) RandServerHearbeat() time.Duration {
return time.Duration(s.c.Protocol.MinHeartbeat) + time.Duration(rand.Int63n(int64(s.c.Protocol.MaxHeartbeat-s.c.Protocol.MinHeartbeat)))
}
// Close close the server.
func (s *Comet) Close() (err error) {
return
}
// Connect connected a connection.
func (s *Comet) Connect(c context.Context, p *comet.Proto) (key string, hb time.Duration, err error) {
var (
req logic.ConnectReq
reply *logic.ConnectReply
)
req.Server = s.serverID
req.Proto = p
reply, err = s.logicRPCClient.Connect(c, &req)
if err != nil {
return
}
return reply.Key, time.Duration(reply.Heartbeat), nil
}
// Disconnect disconnected a connection.
func (s *Comet) Disconnect(c context.Context, key string) (err error) {
_, err = s.logicRPCClient.Disconnect(context.Background(), &logic.DisconnectReq{
Server: s.serverID,
Key: key,
})
return
}
// Heartbeat heartbeat a connection session.
func (s *Comet) Heartbeat(ctx context.Context, key string) (err error) {
_, err = s.logicRPCClient.Heartbeat(ctx, &logic.HeartbeatReq{
Server: s.serverID,
Key: key,
})
return
}
// Receive receive a message.
func (s *Comet) Receive(ctx context.Context, key string, p *comet.Proto) (err error) {
_, err = s.logicRPCClient.Receive(ctx, &logic.ReceiveReq{Key: key, Proto: p})
return
}