Goim Article Series (6 articles in total):

  • Goim architecture and customization
  • From goIM customization, talk about golang interface decoupling and gRPC
  • Basic concepts and applications of Bilibili/Discovery (Eureka) in GOIM
  • Goim data Flow Data flow
  • Goim business Integration (Sharing session summary and QA)
  • What is watchOps listening for in Goim?

Here’s the question github.com/Terry-Mao/g…

The queries referred to were:

For watchOps, the understanding of room should be biased.

WatchOps = section watchOps = section watchRooms

2. The NeedPush method inside is used to determine whether the Operate can be pushed.

3, Operate and deal the Op is int32, just also means operating id.

4. Roomid is a string.

Each CH has a set of Operate when the login is successful. When a message is broadcast, determine whether to listen for the operation. If it does, push it down.

Of course, it is completely used as a room ID and can also realize the function of monitoring messages from other rooms. However, from the point of view of 1 and 4 mentioned above, it does not resemble the meaning of room ID.

Mention me, and have this answer. This answer to look at some source code before and after reading. The following are the answers.


Such an old discussion is still active…………

Is this a room at watchOps? Probably not……………

Look at the code:

The definition of operation comes from here

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"];
}
Copy the code

Specific operation value defined here/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)
)

Copy the code

Notice that OpSub = int32(14)

In channel.go, there is a method definition where op is used as the watchOps key and the value is an empty 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()
}
Copy the code

The Watch method, which is referenced in Comet /operation.go, is called func (s *Server) Operate…….. The server_tcp.go/server_websocket.go service is used in detail (I don’t want to add another description, the code clearly indicates the usage scenario)

// Operate operate.
func (s *Server) Operate(ctx context.Context, p *model.Proto, ch *Channel, b *Bucket) error {
	switch p.Op {
	case model.OpChangeRoom:
		iferr := 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
		iferr := 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
}

Copy the code

Please pay attention to this sentence

	case model.OpSub:
		if ops, err := strings.SplitInt32s(string(p.Body), ","); err == nil {
			ch.Watch(ops...)
		}
Copy the code

So it’s obvious that ops is from p. body by splitting “XXXX, XXXX, XXXX” with “,” and converting it to int32 by strings.splitInt32s.

So, what content exists in p.body in the form of “XXXX, XXXX, XXXX”?

It’s up to you to find the final little answer.

At the very least, illustrates the watchOps the int32 not/API/comet/GRPC/operation defined in the go operation

Above, I wish health and happiness.

2020/02/20 Tsingson in Shenzhen. Nanshan. Xiao Luo Harmonica Music Center