goim 中的 watchOps 在監聽什麼?

問題在這裏github.com/Terry-Mao/g…git

提到的詢問是:github

對於watchOps的理解,理解成房間應該是有誤差的。web

一、watchOps = watchOperate的切片,意思是監聽操做的意思,而不是watchRooms。json

二、裏面的NeedPush方法,來判斷是否擁有這個Operate,才能推送。api

三、Operate恰好和協議裏面的Op都是int32,也是操做id的意思。bash

四、roomid是string類型。websocket

綜上所述,應該是當登陸成功,每一個ch都擁有一組Operate。當廣播消息的時候,判斷是否監聽這個操做,有監聽,就推送下去。socket

固然徹底當作房間id來用,也是徹底能實現監聽其餘房間消息的做用,只是從我上面提的一、4這2點來看,不像房間id的意思。tcp

提到我, 而有此答. 以此答來再看一些源代碼的先後關聯閱讀. 如下爲答覆.ui


這麼老的討論依然活躍啊............

watchOps 這裏是否是房間呢? 有可能不是...............

看代碼:

operation 的定義, 來自這裏

syntax = "proto3";

package goim.comet;
option go_package = "grpc";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

/*
 * v1.0.0
 * protocol
 */
message Proto {
    int32 ver = 1 [(gogoproto.jsontag) = "ver"];
    int32 op = 2 [(gogoproto.jsontag) = "op"];
    int32 seq = 3 [(gogoproto.jsontag) = "seq"];
    bytes body = 4 [(gogoproto.jsontag) = "body"];
}
複製代碼

具體的 operation 值定義在這裏 /api/comet/grpc/operation.go

package grpc

const (
	// OpHandshake handshake
	OpHandshake = int32(0)
	// OpHandshakeReply handshake reply
	OpHandshakeReply = int32(1)

	// OpHeartbeat heartbeat
	OpHeartbeat = int32(2)
	// OpHeartbeatReply heartbeat reply
	OpHeartbeatReply = int32(3)

	// OpSendMsg send message.
	OpSendMsg = int32(4)
	// OpSendMsgReply  send message reply
	OpSendMsgReply = int32(5)

	// OpDisconnectReply disconnect reply
	OpDisconnectReply = int32(6)

	// OpAuth auth connnect
	OpAuth = int32(7)
	// OpAuthReply auth connect reply
	OpAuthReply = int32(8)

	// OpRaw raw message
	OpRaw = int32(9)

	// OpProtoReady proto ready
	OpProtoReady = int32(10)
	// OpProtoFinish proto finish
	OpProtoFinish = int32(11)

	// OpChangeRoom change room
	OpChangeRoom = int32(12)
	// OpChangeRoomReply change room reply
	OpChangeRoomReply = int32(13)

	// OpSub subscribe operation
	OpSub = int32(14)
	// OpSubReply subscribe operation
	OpSubReply = int32(15)

	// OpUnsub unsubscribe operation
	OpUnsub = int32(16)
	// OpUnsubReply unsubscribe operation reply
	OpUnsubReply = int32(17)
)

複製代碼

注意這個 OpSub = int32(14)

在 channel.go 裏 , 這裏有個方法定義, op 被使用爲 watchOps 的鍵, 而值是一個空的 struct

// Watch watch a operation.
func (c *Channel) Watch(accepts ...int32) {
	c.mutex.Lock()
	for _, op := range accepts {
		c.watchOps[op] = struct{}{}
	}
	c.mutex.Unlock()
}
複製代碼

這個 Watch 方法, 在 comet/operation.go 裏被引用 這個方法 func (s *Server) Operate........ 用在 comet 服務的 server_tcp.go / server_websocket.go 中能看到詳細用法( 不另加說明了, 代碼很清楚代表了使用場景)

// Operate operate.
func (s *Server) Operate(ctx context.Context, p *model.Proto, ch *Channel, b *Bucket) error {
	switch p.Op {
	case model.OpChangeRoom:
		if err := b.ChangeRoom(string(p.Body), ch); err != nil {
			log.Errorf("b.ChangeRoom(%s) error(%v)", p.Body, err)
		}
		p.Op = model.OpChangeRoomReply
	case model.OpSub:
		if ops, err := strings.SplitInt32s(string(p.Body), ","); err == nil {
			ch.Watch(ops...)
		}
		p.Op = model.OpSubReply
	case model.OpUnsub:
		if ops, err := strings.SplitInt32s(string(p.Body), ","); err == nil {
			ch.UnWatch(ops...)
		}
		p.Op = model.OpUnsubReply
	default:
		// TODO ack ok&failed
		if err := s.Receive(ctx, ch.Mid, p); err != nil {
			log.Errorf("s.Report(%d) op:%d error(%v)", ch.Mid, p.Op, err)
		}
		p.Body = nil
	}
	return nil
}

複製代碼

請注意這句

case model.OpSub:
		if ops, err := strings.SplitInt32s(string(p.Body), ","); err == nil {
			ch.Watch(ops...)
		}
複製代碼

明顯可見, ops 是從 p.Body 裏, 經過 strings.SplitInt32s 對 "xxxx,xxxx,xxxx" 以 "," 拆分並轉化爲 int32 獲得的.

那麼, 什麼內容以 "xxxx,xxxx,xxxx" 的形式存在 p.Body 裏呢???

這個最終的小答案, 就由你們來尋找吧.

至少, 說明了 watchOps 這個 int32 並非 /api/comet/grpc/operation.go 裏定義的 operation

以上, 祝安康,愉快.

2020/02/20 tsingson 於 深圳.南山.小羅號口琴音樂中心

相關文章
相關標籤/搜索