im

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2023 License: LGPL-3.0 Imports: 33 Imported by: 0

README

IM

一个基于websocket的聊天简单工具

可以分布式运行,一台机器也可以启几个,但需要改运行端口 服务器之间通过GRPC 通讯。

然后使用网页打开,比如:

http://127.0.0.1:7070/index?msg=1

http://127.0.0.1:7071/index?msg=1

http://127.0.0.1:7072/index?msg=1

相关GRPC测试,可以通过POSTMAN, img.png

Documentation

Index

Constants

View Source
const (
	ETException = EventType(1)

	ETClientPing    = EventType(2)
	ETClientPingRsp = EventType(3)

	// ETClientBegin 客户端开始
	ETClientBegin        = EventType(10)
	ETClientHeartBeat    = EventType(10)
	ETClientHeartBeatRsp = EventType(11)

	// ETClientLogin 登录
	ETClientLogin    = EventType(100)
	ETClientLoginRsp = EventType(101)

	ETClientLogout    = EventType(102)
	ETClientLogoutRsp = EventType(103)

	// ETClientUserStatusChanged 用户状态发生变化
	ETClientUserStatusChanged    = EventType(104)
	ETClientUserStatusChangedRes = EventType(105)

	ETClientUserList    = EventType(106)
	ETClientUserListRsp = EventType(107)

	// ETClientKicked 多端使用,被踢
	ETClientKicked = EventType(108)

	// ETMessage 消息事件
	ETMessage    = EventType(200)
	ETMessageRsp = EventType(201)

	ETNotify    = EventType(202)
	ETNotifyRsp = EventType(203)

	// ETChat 聊天事件
	ETChat    = EventType(204)
	ETChatRsp = EventType(205)

	// ETClientEnd 客户端结束
	ETClientEnd = EventType(4999)

	// ETServerBegin 服务之间
	ETServerBegin = EventType(5000)

	ETServerEnd = EventType(10000)

	// ETExServerBegin 外部服务
	ETExServerBegin = EventType(20000)

	ETExServerEnd = EventType(30000)

	// ETHungUp 电话区间
	ETHungUp    = EventType(50000)
	ETHungUpRsp = EventType(50001)

	ETAppCall    = EventType(50002)
	ETAppCallRsp = EventType(50003)

	// ETCallTransfer 将当前通道转接到某个用户
	ETCallTransfer    = EventType(50004)
	ETCallTransferRsp = EventType(50005)

	// ETCallListen 监听电话
	ETCallListen    = EventType(50006)
	ETCallListenRsp = EventType(50007)

	ETCallout2    = EventType(50008)
	ETCallout2Rsp = EventType(50009)

	ETCallout    = EventType(50010)
	ETCalloutRsp = EventType(50011)
)
View Source
const (
	StatusOffline   = 1
	StatusOnline    = 2
	StatusHeartbeat = 3
)
View Source
const UserHeartbeatTimeout = int64(time.Minute * 3)

UserHeartbeatTimeout 3分钟

Variables

View Source
var IAmNotMemberErr = errors.New("i am not member")
View Source
var (
	KEmptyByte = []byte("")
)
View Source
var NotExistRemoteServer = result.Error(-100, "not exist remote server")
View Source
var StatusDesc = map[int32]string{
	StatusOffline: "离开",
	StatusOnline:  "在线",
}

Functions

func ContentQuote

func ContentQuote(d interface{}) string

func IsClientEvent

func IsClientEvent(ev int32) bool

func IsExServerEvent

func IsExServerEvent(ev int32) bool

func IsServerEvent

func IsServerEvent(ev int32) bool

func IsUserStatusChanged

func IsUserStatusChanged(ev int32) bool

func Register

func Register(key int32, value DisposeFunc)

func SessionToPBSession

func SessionToPBSession(session *Session, token string) *pb.Session

func SessionToPBUser

func SessionToPBUser(session *Session) *pb.User

func ToPBEvent

func ToPBEvent(ev *Event) *pb.Event

Types

type App

type App struct {
	AppId string `form:"appId" binding:"required" json:"appId"`
	Plat  int32  `form:"plat" binding:"-" json:"plat"`
}

type ArrayCopy

type ArrayCopy struct {
	Begin   func(count int) interface{}
	Process func(be interface{}, index int, data interface{})
}

type Client

type Client struct {
	User       Session
	Conn       *websocket.Conn // 用户连接
	ClientId   uint64
	ConnectId  uint64
	Index      int64
	Addr       string // 客户端地址
	Token      string
	InUserList bool // 是否在 IM.userClient
	// contains filtered or unexported fields
}

func NewClient

func NewClient(im *IM, addr string, conn *websocket.Conn, firstTime int64, connect Connect) *Client

func (*Client) Heartbeat

func (c *Client) Heartbeat(currentTime int64)

func (*Client) IsClosed

func (c *Client) IsClosed() bool

func (*Client) IsHeartbeatTimeout

func (c *Client) IsHeartbeatTimeout(currentTime int64) bool

func (*Client) IsLogin

func (c *Client) IsLogin() bool

func (*Client) IsSameAppId

func (c *Client) IsSameAppId(session *Session) bool

func (*Client) IsSamePlat

func (c *Client) IsSamePlat(session *Session) bool

func (*Client) Login

func (c *Client) Login(user *Session, loginTime int64)

func (*Client) Logout

func (c *Client) Logout(logoutTime int64)

func (*Client) SendTo

func (c *Client) SendTo(msg []byte) error

func (*Client) SendToQueue

func (c *Client) SendToQueue(msg []byte) error

func (*Client) String

func (c *Client) String() string

type Config

type Config struct {
	WorkForceReset bool
	ServerAddr     server.Address `json:"-"` //服务地址
	// contains filtered or unexported fields
}

type Connect

type Connect struct {
	Session
	Version string `json:"version"`
}

type DisposeFunc

type DisposeFunc func(client *Client, req *EventReq) (interface{}, error)

type Event

type Event struct {
	// 事件基数
	EvTypeBase int32 `json:"-"`

	// 事件类型, EventType
	EventType int32 `json:"eventType"`

	// Content 格式,json,xml...protobuff, 默认json
	ContentType string `json:"contentType"`

	// 具体的业务数据
	Content string `json:"content"`
}

func CreateEvent

func CreateEvent(evType EventType, content []byte) *Event

func CreateEventWithContent

func CreateEventWithContent(evType EventType, content interface{}) *Event

func PBEventTo

func PBEventTo(ev *pb.Event) *Event

type EventReq

type EventReq struct {
	ReqHead
	Event
	Session
	// 事件相应的回应类型
	EvTypeRsp int32 `json:"-"`
}

func Request

func Request(source string, user *Session) *EventReq

func RequestEvent

func RequestEvent(source string, ev *Event, user *Session) *EventReq

func (*EventReq) ToBytes

func (req *EventReq) ToBytes() []byte

func (*EventReq) ToSession

func (req *EventReq) ToSession() *Session

type EventRes

type EventRes struct {
	ResHead
	Event
}

func NewResponse

func NewResponse(source string, head request.HeadV2, result result.Result, ev *Event) *EventRes

func NewResponseWithError

func NewResponseWithError(source string, head request.HeadV2, err error, ev *Event) *EventRes

type EventType

type EventType int32

func (EventType) Int

func (m EventType) Int() int32

type Group

type Group struct {
	GId   int64
	Plat  int32
	AppId string
	// contains filtered or unexported fields
}

Group 群

func (*Group) CheckMember

func (g *Group) CheckMember(chatGroup chat.Group, from *Session) ([]chat.MemberId, bool)

func (*Group) Enter

func (g *Group) Enter(chatGroup chat.Group, user *chat.Member, option *chat.Option)

func (*Group) Enters

func (g *Group) Enters(chatGroup chat.Group, members []chat.Member, option *chat.Option)

func (*Group) Leave

func (g *Group) Leave(chatGroup chat.Group, userId chat.MemberId, option *chat.Option)

func (*Group) Leaves

func (g *Group) Leaves(chatGroup chat.Group, members []chat.Member, option *chat.Option)

func (*Group) Remove

func (g *Group) Remove(chatGroup chat.Group, option *chat.Option)

func (*Group) Send

func (g *Group) Send(chatGroup chat.Group, from *Session, amMemberFn IAmMemberFunc, fn MemberFunc) error

func (*Group) String

func (g *Group) String() string

func (*Group) UpdateVersion

func (g *Group) UpdateVersion(chatGroup chat.Group, option *chat.Option)

type GroupMgr

type GroupMgr struct {
	// contains filtered or unexported fields
}

func NewGroupMgr

func NewGroupMgr() *GroupMgr

func (*GroupMgr) CreateGroup

func (mgr *GroupMgr) CreateGroup(from *Session, group *chat.GroupModel, option *chat.Option) error

func (*GroupMgr) DeleteGroup

func (mgr *GroupMgr) DeleteGroup(from *Session, groupId int64, option *chat.Option) error

func (*GroupMgr) GetGroup

func (mgr *GroupMgr) GetGroup(groupKey string) (*Group, error)

func (*GroupMgr) JoinGroup

func (mgr *GroupMgr) JoinGroup(from *Session, group *chat.GroupModel, option *chat.Option) error

func (*GroupMgr) LeaveGroup

func (mgr *GroupMgr) LeaveGroup(from *Session, group *chat.GroupModel, option *chat.Option) error

func (*GroupMgr) OfflineGroups

func (mgr *GroupMgr) OfflineGroups(from *Session)

OfflineGroups 用户离线

func (*GroupMgr) OnlineGroups

func (mgr *GroupMgr) OnlineGroups(from *Session)

OnlineGroups 用户上线,需要初始化群组路由

func (*GroupMgr) Send

func (mgr *GroupMgr) Send(from *Session, chat *chat.Message, amMemberFn IAmMemberFunc, fn MemberFunc) error

func (*GroupMgr) WithChatGroup

func (mgr *GroupMgr) WithChatGroup(group chat.Group)

type IAmMemberFunc

type IAmMemberFunc func(user *Session, iAmMember bool) error

IAmMemberFunc 是否是群成员, iAmMember= true 是成员

type IM

type IM struct {
	// contains filtered or unexported fields
}

func Inst

func Inst() *IM

func NewIM

func NewIM() *IM

func (*IM) AddClients

func (im *IM) AddClients(client *Client)

func (*IM) AddUsers

func (im *IM) AddUsers(key string, client *Client)

func (*IM) CheckAllUserOnline

func (im *IM) CheckAllUserOnline(session *Session) bool

func (*IM) CheckUserOnline

func (im *IM) CheckUserOnline(session *Session) bool

CheckUserOnline 查询用户是否在线

func (*IM) ClearTimeoutConnections

func (im *IM) ClearTimeoutConnections()

func (*IM) ClientsRange

func (im *IM) ClientsRange(f func(client *Client) (result bool))

func (*IM) DelClients

func (im *IM) DelClients(client *Client)

func (*IM) DelUsers

func (im *IM) DelUsers(client *Client) bool

func (*IM) GetAllUserList

func (im *IM) GetAllUserList(session *Session) *UserList

GetAllUserList 查询所有用户

func (*IM) GetClients

func (im *IM) GetClients() []*Client

func (*IM) GetLocalUserList

func (im *IM) GetLocalUserList(session *Session) *UserList

GetLocalUserList 本机的用户

func (*IM) GetServerHost

func (im *IM) GetServerHost() string

func (*IM) GetServerPort

func (im *IM) GetServerPort() int

func (*IM) GetServers

func (im *IM) GetServers() []builder.Address

func (*IM) GetUserClient

func (im *IM) GetUserClient(session *Session) *Client

func (*IM) GrpcClient

func (im *IM) GrpcClient() rpc.IMClient

func (*IM) Handler

func (im *IM) Handler(connect Connect, w http.ResponseWriter, r *http.Request)

func (*IM) InClient

func (im *IM) InClient(client *Client) (ok bool)

func (*IM) Init

func (im *IM) Init(client discoveryservice.Client, rpcClient rpc.IMClient, user User, chat chat.Group, cfg Config)

func (*IM) IsLocalAddress

func (im *IM) IsLocalAddress(server string) bool

func (*IM) RateLimit

func (im *IM) RateLimit(session Session, version string) bool

func (*IM) ReceiveFromExServer

func (im *IM) ReceiveFromExServer(from *Session, to *Session, ev *Event, defHandler func())

ReceiveFromExServer 收到外服务器的消息

func (*IM) ReceiveToLocal

func (im *IM) ReceiveToLocal(from *Session, to *Session, ev *Event)

ReceiveToLocal 收到服务器之间的消息

func (*IM) SendChat

func (im *IM) SendChat(from *Session, ev *Event, option chat.Option, handler func()) error

func (*IM) SendToAllUser

func (im *IM) SendToAllUser(from *Session, to *Session, ev *Event, custom interface{})

SendToAllUser 给全体用户发消息

func (*IM) SendToLocalAppId

func (im *IM) SendToLocalAppId(from *Session, to *Session, ev *Event, custom interface{})

SendToLocalAppId 给本地 指定的客户端appid 送消息到, 除了userId

func (*IM) SendToLocalUser

func (im *IM) SendToLocalUser(from *Session, to *Session, ev *Event) (error, bool)

SendToLocalUser 给本机指定用户发送消息

func (*IM) SendToRemote

func (im *IM) SendToRemote(from *Session, to *Session, ev *Event)

SendToRemote 发送到远端

func (*IM) SendToRemoteAppId

func (im *IM) SendToRemoteAppId(addr string, from *Session, to *Session, ev *Event)

func (*IM) SendToRemoteUser

func (im *IM) SendToRemoteUser(from *Session, to *Session, ev *Event) error

func (*IM) SendToUser

func (im *IM) SendToUser(from *Session, to *Session, ev *Event) error

SendToUser 给指定在线用户发送消息

func (*IM) SyncToRemoteOnly

func (im *IM) SyncToRemoteOnly(from *Session, to *Session, ev *Event)

SyncToRemoteOnly 仅仅只同步到远端

func (*IM) UnInit

func (im *IM) UnInit()

func (*IM) UserMgr

func (im *IM) UserMgr() User

func (*IM) WithGroupModel

func (im *IM) WithGroupModel(chat chat.Group) *IM

func (*IM) WithGrpcClient

func (im *IM) WithGrpcClient(grpc rpc.IMClient) *IM

func (*IM) WithUserMgr

func (im *IM) WithUserMgr(user User) *IM

type MemberFunc

type MemberFunc func(groupId int64, user *Session) error

type Online

type Online struct {
	AppId  string `json:"appId"`
	UserId uint64 `json:"userId"`
	Plat   int32  `json:"plat"`
	// 用户所在的服务器ip
	Host string `json:"host,omitempty"`
	// 用户所在的服务器端口
	Port int `json:"port,omitempty"`
	// 客户端Ip
	ClientIp string `json:"clientIp,omitempty"`
	// 客户端端口
	ClientPort string `json:"clientPort,omitempty"`
	// 用户上次登录时间
	LoginTime int64 `json:"loginTime,omitempty"`
	// 用户上次心跳时间
	HeartbeatTime int64 `json:"heartbeatTime,omitempty"`
	// 用户退出登录的时间
	LogOutTime int64 `json:"logOutTime,omitempty"`
	// 是否离线
	IsOffline bool `json:"isOffline"`
}

func (*Online) Heartbeat

func (u *Online) Heartbeat(currentTime int64)

func (*Online) IsLocal

func (u *Online) IsLocal(localIp string, localPort int) bool

IsLocal 用户是否在本台机器上

func (*Online) IsOnline

func (u *Online) IsOnline(heartCheck func(heartbeat int64) bool) bool

func (*Online) LogIn

func (u *Online) LogIn(currentTime int64)

func (*Online) LogOut

func (u *Online) LogOut(currentTime int64)

func (*Online) String

func (u *Online) String() string

type Option

type Option struct {
	CrmNotifyEnable bool
}

type ReqHead

type ReqHead struct {
	Source  string        `json:"source"`
	Version string        `json:"version"`
	SeqId   string        `json:"seqId"`
	ReqAt   int64         `json:"timeAt"` //客户端或服务器的时间
	RecvAt  int64         `json:"-"`      //服务器收到的时间
	TimeOut time.Duration `json:"-"`
}

func (*ReqHead) GetRecvAt

func (h *ReqHead) GetRecvAt() int64

GetRecvAt request.HeadV2 interface

func (*ReqHead) GetReqAt

func (h *ReqHead) GetReqAt() int64

GetReqAt request.HeadV2 interface

func (*ReqHead) GetSeqId

func (h *ReqHead) GetSeqId() string

GetSeqId request.Head interface

func (*ReqHead) GetSource

func (h *ReqHead) GetSource() string

GetSource request.Head interface

func (*ReqHead) GetTimeOut

func (h *ReqHead) GetTimeOut() time.Duration

GetTimeOut request.HeadV2 interface

func (*ReqHead) GetVersion

func (h *ReqHead) GetVersion() string

GetVersion request.Head interface

func (*ReqHead) SetSource

func (h *ReqHead) SetSource(source string)

SetSource request.HeadV2 interface

func (*ReqHead) SetTimeOut

func (h *ReqHead) SetTimeOut(duration time.Duration)

SetTimeOut request.HeadV2 interface

type ResHead

type ResHead struct {
	result.Result
	Version  string `json:"version"`            //版本,请求者版本
	Source   string `json:"source,omitempty"`   //请求源,可以请求者填写
	SeqId    string `json:"seqId,omitempty"`    //请求序号,由请求者定义,服务器原路返回
	TimeAt   int64  `json:"timeAt,omitempty"`   //服务收到请求的时间(ms)
	DiffAt   int64  `json:"diffAt,omitempty"`   //客户端与服务端时间差值(ms)
	SpendAt  int64  `json:"spendAt,omitempty"`  //从服务收到请求到响应完成,所花的时长(ms)
	ServerAt int64  `json:"serverAt,omitempty"` //服务器时间,豪秒,用于检验对时(ms)
	LogId    string `json:"logId,omitempty"`
}

func NewResHead

func NewResHead(source string, res result.Result) ResHead

type Session

type Session struct {
	AppId    string `form:"appId" binding:"required" json:"appId"`
	Plat     int32  `form:"plat" binding:"-" json:"plat"`
	UserId   uint64 `form:"userId" binding:"required" json:"userId"`
	ClientId uint64 `form:"clientId" binding:"-" json:"clientId"`
}

func PBSessionToSession

func PBSessionToSession(session *pb.Session) Session

func PBUserToSession

func PBUserToSession(u *pb.User) Session

func (*Session) String

func (s *Session) String() string

type Status

type Status struct {
	Session
	TimeAt int64  `json:"timeAt"`
	Status int32  `json:"status"`
	Desc   string `json:"desc"`
}

func (*Status) String

func (s *Status) String() string

type User

type User interface {
	SetSupportApp(apps []App)
	NextSupportApp(fn func(app App) bool)
	ExistSupportApp(app App) bool
	HeartbeatTimeout() int64
	GetUserKey(session *Session) string
	GetUserOnline(session *Session) (*Online, error)
	// SetUserOnline 写到redis中
	SetUserOnline(session *Session, online *Online) error
	RemoveUserOnline(session *Session) error
	IsUserOnline(session *Session) (bool, error)

	GetAllOnline(cc *ArrayCopy, session *Session) error

	//UserStatusChanged 通知基它服务有变化
	UserStatusChanged(status *Status, option *Option)
}

type UserList

type UserList struct {
	Count int        `json:"count"`
	List  []*Session `json:"list,omitempty"`
}

type Work

type Work struct {
	// contains filtered or unexported fields
}

func (*Work) Add

func (wk *Work) Add(client *Client)

func (*Work) Del

func (wk *Work) Del(client *Client)

func (*Work) Send

func (wk *Work) Send(local *localData)

func (*Work) Start

func (wk *Work) Start()

func (*Work) Stop

func (wk *Work) Stop()

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL