pico

package module
v0.0.0-...-3e95572 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2024 License: MIT Imports: 14 Imported by: 0

README

PICO

PICO是一个简单的物联网通讯协议,基于TCP/IP协议, 适用于网关与服务器之间,服务器与服务器之间通讯。 协议参考了MQTT及其他总线协议设计,支持请求/响应模式、订阅发布,和数据流。

一、包头

1.1 固定头(10个字节)
标识 长度(位) 说明
魔术头 32 "PICO"
包序号 16 0-65535,客户端服务端各自维持
包类型 4 0-15
数据格式 4 0-15
数据长度 24 0-16777216,0-16MB
1.2 包类型
id 类型 方向 说明
0 DISCONNECT 双向 关闭连接
1 CONNECT 上行 连接
2 CONNECT_ACK 下行 连接响应
3 PING 双向 ping
4 PONG 双向 pong
5 REQUEST 双向 请求
6 RESPONSE 双向 响应
7 STREAM 双向 数据流
8 STREAM_END 双向 数据流结束
9 PUBLISH 上行 发布
10 PUBLISH_ACK 下行 发布响应
11 SUBSCRIBE 上行 订阅
12 SUBSCRIBE_ACK 下行 订阅响应
13 UNSUBSCRIBE 上行 取消订阅
14 UNSUBSCRIBE_ACK 下行 取消订阅响应
15 MESSAGE 下行 消息
1.3 数据格式
id 类型 说明
0 binary 默认二进制
1 json 通用性强
2 xml 比较老旧,不建议使用
3 yaml 较JSON省流,清晰
4 msgpack 省流,高性能
5-15 custom 自定义

二、包体

2.1 连接和鉴权
CONNECT 连接

连接之后,必须先发送CONNECT包,进行鉴权

首次连接

{
  "username": "user", //用户名
  "password": "123456", //密码
}

再次连接,使用token

{
  "id": "123123123123", //客户端ID
  "token": "xyzxyzxyzxyz", //登录证书
}
CONNECT_ACK 连接响应
{
  "result": "ok/fail", //结果
  "reason": "密码错误", //错误原因
  "id": "123123123123", //客户端ID
  "token": "abcabcabcabc", //登录证书,客户端需要保存
}

客户端收到TOKEN之后应该保存,下次连接使用TOKEN,可以避免密码泄露风险。

为了TOKEN安全,服务端在TOKEN方式鉴权之后,需要重新生成TOKEN,并返回给客户端。

2.2 PING和心跳

PING包用于验证网络是否连接,也可以作为心跳,建议至少5分钟发送一次。 为避免冗余数据,在有频繁数据交换的情况下,可以不发送心跳。

无内容,直接回复PONG

2.3 请求/响应模式

此方式兼容HTTP请求/响应的模式,数据格式为

请求

POST /api/device/list HTTP/1.1  //换行回车
Host:xxx //换行回车
...
//换行回车
{"user":"bob"}

响应

HTTP/1.1 200 OK  //换行回车
Server: Apache //换行回车
...
//换行回车
{"user":"bob"}
2.4 数据流
2.5 订阅模式
2.6 关闭连接
三、扩展规约

Documentation

Index

Constants

View Source
const (
	Magic      = "pico"
	MagicSize  = len(Magic)
	HeaderSize = 10
	BufferSize = 1024
)
View Source
const (
	DISCONNECT uint8 = iota
	CONNECT
	CONNECT_ACK
	PING
	PONG
	REQUEST
	RESPONSE
	STREAM
	STREAM_END
	PUBLISH
	PUBLISH_ACK
	SUBSCRIBE
	SUBSCRIBE_ACK
	UNSUBSCRIBE
	UNSUBSCRIBE_ACK
)
View Source
const (
	BINARY uint8 = iota
	JSON
	XML
	YAML
	MSGPACK
)

Variables

This section is empty.

Functions

func RegisterEncoding

func RegisterEncoding(typ uint8, encoder Encoder, decoder Decoder)

Types

type Auth

type Auth struct {
	Id    string `json:"id"`
	Token string `json:"token"`
}

type Client

type Client struct {
	Pico
}

func (*Client) Connect

func (c *Client) Connect() error

func (*Client) Disconnect

func (c *Client) Disconnect(reason string)

func (*Client) Publish

func (c *Client) Publish(topic string, message any) error

func (*Client) Subscribe

func (c *Client) Subscribe(filters []string) error

func (*Client) Unsubscribe

func (c *Client) Unsubscribe(filters []string) error

type Connect

type Connect struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

type ConnectAck

type ConnectAck struct {
	Result bool  `json:"result"`
	Auth   *Auth `json:"auth,omitempty"`
}

type Decoder

type Decoder func([]byte, any) error

type Disconnect

type Disconnect struct {
	Reason string `json:"reason,omitempty"`
}

type Encoder

type Encoder func(any) ([]byte, error)

type Incoming

type Incoming struct {
	Pico
	// contains filtered or unexported fields
}

func (*Incoming) Disconnect

func (c *Incoming) Disconnect(reason string)

type Map

type Map[K comparable, V any] struct {
	// contains filtered or unexported fields
}

func (*Map[K, V]) Clear

func (c *Map[K, V]) Clear()

func (*Map[K, V]) Delete

func (c *Map[K, V]) Delete(key K)

func (*Map[K, V]) DeleteDirectly

func (c *Map[K, V]) DeleteDirectly(key K)

func (*Map[K, V]) Len

func (c *Map[K, V]) Len() int

func (*Map[K, V]) Load

func (c *Map[K, V]) Load(key K) *V

func (*Map[K, V]) LoadAndDelete

func (c *Map[K, V]) LoadAndDelete(key K) *V

func (*Map[K, V]) LoadAndStore

func (c *Map[K, V]) LoadAndStore(key K, value *V) *V

func (*Map[K, V]) Map

func (c *Map[K, V]) Map() map[K]*V

func (*Map[K, V]) Range

func (c *Map[K, V]) Range(iterator func(key K, item *V) bool)

func (*Map[K, V]) Store

func (c *Map[K, V]) Store(key K, value *V)

type Message

type Message struct {
	Topic   string `json:"topic"`
	Message any    `json:"message"`
}

type Pack

type Pack struct {
	Id       uint16
	Type     uint8
	Encoding uint8
	Payload  []byte
	Content  any
}

func (*Pack) Decode

func (p *Pack) Decode(payload any) (err error)

func (*Pack) Encode

func (p *Pack) Encode() (err error)

type Pico

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

func (*Pico) Ask

func (p *Pico) Ask(req *Pack) (resp *Pack, err error)

func (*Pico) AttachHandler

func (p *Pico) AttachHandler(h http.Handler)

func (*Pico) Ping

func (p *Pico) Ping() (ms int, err error)

func (*Pico) Request

func (p *Pico) Request(req *http.Request) (*http.Response, error)

func (*Pico) Send

func (p *Pico) Send(pack *Pack) error

func (*Pico) Stream

func (p *Pico) Stream() (stream *Stream, id uint16)

type Publish

type Publish struct {
	Topic   string `json:"topic"`
	Message any    `json:"message"`
}

type PublishAck

type PublishAck struct {
	Topics map[string]bool `json:"topics"`
}

type Server

type Server struct {
}

func (*Server) Serve

func (s *Server) Serve(port int) error

type Stream

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

func (*Stream) Close

func (s *Stream) Close() error

func (*Stream) Id

func (s *Stream) Id() uint16

func (*Stream) Read

func (s *Stream) Read(buf []byte) (int, error)

func (*Stream) Write

func (s *Stream) Write(buf []byte) (int, error)

type Subscribe

type Subscribe struct {
	Filters []string `json:"filters"`
}

type SubscribeAck

type SubscribeAck struct {
	Filters map[string]bool `json:"filters"`
}

type Unsubscribe

type Unsubscribe struct {
	Filters []string `json:"filters"`
}

type UnsubscribeAck

type UnsubscribeAck struct {
	Filters map[string]bool `json:"filters"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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