stompserver

package module
v0.0.0-...-48ca4bb Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2021 License: Apache-2.0 Imports: 13 Imported by: 0

README

stompserver

go stomp server base on "net/http"

base on "net/http" and "golang.org/x/net/websocket" so use one port, you can be WebServer or StompServer or websocket or both

基于"net/http"和"golang.org/x/net/websocket",所以一个端口,就可以同时实现web服务,websocket,stomp服务.

example

https://github.com/0xAAFF/stompserver_example

使用方式

	//http.HandleFunc("/", HttpVueServer)                                        // Web服务
	//fmt.Println("Web Server  : http://127.0.0.1:", 80, "/")

	http.Handle("/stomp", websocket.Handler(StompServerInstance.NewStompUnit)) // Stomp服务
	fmt.Println("Stomp Server: ws://localhost:", 80, "/stomp")

see www_example.go

模块使用说明

/example/

  • Web 网页解析模块

    1. 模块路径 server_web.go
    2. 填充代码 实现接口 -> onReflex server_web.go已经实现了针对Vue2/3/4 build项目的文件支持, 后期调用接口主要写在func onReflex(responseW http.ResponseWriter, request *http.Request)函数中 当然,因为项目已经支持了Stomp协议,建议项目中此模块只用于网页资源的解析即可
    3. 测试建议
      • 基础web资源解析(通过浏览器可以访问到web项目中的各种资源,html,js,css,图片,字体等web资源)
      • 针对web路径做安全测试,例如访问js目录中非js文件,或者构造其他路径,使得程序奔溃,或者构造伪装路径获取其他目录资源,甚至构造路径尝试执行代码等
  • Stomp 模块

    1. 模块路径 server_stomp.go
    2. 填充代码,实现接口
      • 配置群发,组发,单发地址 server_stomp.go->init() 在init()中,需要实现两个:注册群发组发单发的根地址标识 和 注册可被客户端订阅的地址

      • 实现每个订阅地址的实际功能 ./service/kernel/stomp_reflex.go->Reflex(sourceStompMessage *xstomp.Frame, unit *xstomp.StompUnit) 在Reflex(sourceStompMessage *xstomp.Frame, unit *xstomp.StompUnit)函数中,实现针对每个地址的接口访问 这样的好处是一处提交,数据同步所有客户端,对于状态改变等非常迅速.主要实现的接口将在此处

/*******************************************************************************
 *
 *  Copyright (c) 2021 0xAAFF<littletools@outlook.com>
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * 
 *******************************************************************************/

AboutMe

MyPage

Documentation

Overview

package stompserver provides functionality for manipulating STOMP frames.

Index

Constants

View Source
const (
	AckAuto             = "auto"              // Client does not send ACK
	AckClient           = "client"            // Client sends ACK/NACK
	AckClientIndividual = "client-individual" // Client sends ACK/NACK for individual messages
)

Valid values for the "ack" header entry.

View Source
const (
	// Client commands.
	CommandAbort       = "ABORT"
	CommandACK         = "ACK"
	CommandBegin       = "BEGIN"
	CommandCommit      = "COMMIT"
	CommandConnect     = "CONNECT"
	CommandDisconnect  = "DISCONNECT"
	CommandNack        = "NACK"
	CommandSend        = "SEND"
	CommandStomp       = "STOMP"
	CommandSubscribe   = "SUBSCRIBE"
	CommandUnsubscribe = "UNSUBSCRIBE"

	// Server commands.
	CommandConnected = "CONNECTED"
	CommandError     = "ERROR"
	CommandMessage   = "MESSAGE"
	CommandHeartbeat = "RECEIPT"
)

STOMP frame commands. Used upper case naming convention to avoid clashing with STOMP header names.

View Source
const (
	AcceptVersion = "accept-version"
	Ack           = "ack"
	ContentLength = "content-length"
	ContentType   = "content-type"
	Destination   = "destination"
	HeartBeat     = "heart-beat"
	Host          = "host"
	Id            = "id"
	Login         = "login"
	Message       = "message"
	MessageId     = "message-id"
	Passcode      = "passcode"
	Receipt       = "receipt"
	ReceiptId     = "receipt-id"
	Server        = "server"
	Session       = "session"
	Subscription  = "subscription"
	Transaction   = "transaction"
	Version       = "version"
)

STOMP header names. Some of the header names have commands with the same name (eg Ack, Message, Receipt). Commands use an upper-case naming convention, header names use pascal-case naming convention.

View Source
const (
	Plain    = "text/plain"
	Html     = "text/html"
	Xml      = "text/xml"
	RichText = "text/richtext"
)

Text

View Source
const (
	Soap  = "application/soap+xml"
	Octet = "application/octet-stream"
	Rtf   = "application/rtf"
	Pdf   = "application/pdf"
	Zip   = "application/zip"
)

Application

View Source
const (
	Gif  = "image/gif"
	Tiff = "image/tiff"
	Jpeg = "image/jpeg"
)

Image

View Source
const (
	Unknow = -1
	All    = iota
	Application
	User
)

Variables

View Source
var (
	ErrInvalidCommand     = errors.New("invalid command")
	ErrInvalidFrameFormat = errors.New("invalid frame format")
)
View Source
var (
	ErrInvalidHeartBeat = errors.New("invalid heart-beat")
)
View Source
var InstancesStompManager = &StompManager{
	rootMux:                           new(sync.Mutex),
	rootDestinationSliceToAll:         []string{},
	rootDestinationSliceToApplication: []string{},
	rootDestinationSliceToUser:        []string{},
	guid:                              tools.TimeUUID().String(),
	giudMux:                           new(sync.Mutex),
	messageTailId:                     uint64(0),
	subscribeSupportTopicSlice:        []string{},
	stompSubscribeDictionary:          make(map[string]map[string]StompUnit),
	stompSubscribeDictionaryMux:       new(sync.Mutex),
}
View Source
var StompCommand = &command{

	Abort:       "ABORT",
	ACK:         "ACK",
	Begin:       "BEGIN",
	Commit:      "COMMIT",
	Connect:     "CONNECT",
	Disconnect:  "DISCONNECT",
	Nack:        "NACK",
	Send:        "SEND",
	Stomp:       "STOMP",
	Subscribe:   "SUBSCRIBE",
	Unsubscribe: "UNSUBSCRIBE",

	Connected: "CONNECTED",
	Error:     "ERROR",
	Message:   "MESSAGE",
	Heartbeat: "RECEIPT",
}
View Source
var StompHeaders = &headerKey{
	AcceptVersion: "accept-version",
	Ack:           "ack",
	ContentLength: "content-length",
	ContentType:   "content-type",
	Destination:   "destination",
	HeartBeat:     "heart-beat",
	Host:          "host",
	Id:            "id",
	Login:         "login",
	Message:       "message",
	MessageId:     "message-id",
	Passcode:      "passcode",
	Receipt:       "receipt",
	ReceiptId:     "receipt-id",
	Server:        "server",
	Session:       "session",
	Subscription:  "subscription",
	Transaction:   "transaction",
	Version:       "version",
}

Functions

func IsClientCommand

func IsClientCommand(command string) (bool, error)

IsClientCommand 验证是否是客户端的命令

参数:
command	string	包命令
return	bool	true 客户端的包 false 异常包(应该发送一个Error包,然后关闭连接)
      	error	nil / 无效包错误

func IsServerCommand

func IsServerCommand(command string) (bool, error)

IsServerCommand 是否是server的包

参数:
command	string	包命令
return	bool	true 服务端的包 false 异常包(应该发送一个Error包,然后关闭连接)
      	error	nil / 无效包错误

func ParseHeartBeat

func ParseHeartBeat(heartBeat string) (time.Duration, time.Duration, error)

ParseHeartBeat parses the value of a STOMP heart-beat entry and returns two time durations. Returns an error if the heart-beat value is not in the correct format, or if the time durations are too big to be represented by the time.Duration type.

Types

type Frame

type Frame struct {
	Command string
	Header  *Header
	// contains filtered or unexported fields
}

A Frame represents a STOMP frame. A frame consists of a command followed by a collection of header entries, and then an optional body.

func Deserialize

func Deserialize(stompText string) (*Frame, error)

func New

func New(command string, headers ...string) *Frame

New creates a new STOMP frame with the specified command and headers. The headers should contain an even number of entries. Each even index is the header name, and the odd indexes are the assocated header values.

func NewConnectedFrame

func NewConnectedFrame(connectFrame *Frame, session string) *Frame

STOMP 1.2 servers MUST set the following headers:

version : The version of the STOMP protocol the session will be using. See Protocol Negotiation for more details. STOMP 1.2 servers MAY set the following headers:

heart-beat : The Heart-beating settings.

session : A session identifier that uniquely identifies the session.

server : A field that contains information about the STOMP server. The field MUST contain a server-name field and MAY be followed by optional comment fields delimited by a space character.

The server-name field consists of a name token followed by an optional version number token.

server = name ["/" version] *(comment)

Example:

server:Apache/1.3.9

func NewErrorFrame

func NewErrorFrame(tips string, detail string, originFrame *Frame) *Frame

func NewMessageFrame

func NewMessageFrame(destination string, messageID string, subscription string) (*Frame, string)

func (*Frame) Body

func (f *Frame) Body() []byte

func (*Frame) Clone

func (f *Frame) Clone() *Frame

Clone creates a deep copy of the frame and its header. The cloned frame shares the body with the original frame.

func (*Frame) Serialize

func (f *Frame) Serialize() string

func (*Frame) SetBody

func (f *Frame) SetBody(body string)
type Header struct {
	// contains filtered or unexported fields
}

A Header represents the header part of a STOMP frame. The header in a STOMP frame consists of a list of header entries. Each header entry is a key/value pair of strings.

Normally a STOMP header only has one header entry for a given key, but the STOMP standard does allow for multiple header entries with the same key. In this case, the first header entry contains the value, and any subsequent header entries with the same key are ignored.

Example header containing 6 header entries. Note that the second header entry with the key "comment" would be ignored.

login:scott
passcode:tiger
host:stompserver
accept-version:1.0,1.1,1.2
comment:some comment
comment:another comment

func NewHeader

func NewHeader(headerEntries ...string) *Header

NewHeader creates a new Header and populates it with header entries. This function expects an even number of strings as parameters. The even numbered indices are keys and the odd indices are values. See the example for more information.

func (*Header) Add

func (h *Header) Add(key, value string)

Add adds the key, value pair to the header.

func (*Header) AddFromArray

func (h *Header) AddFromArray(array []string)

AddFromArray adds all of the key value pairs in header to h.

func (*Header) AddHeader

func (h *Header) AddHeader(header *Header)

AddHeader adds all of the key value pairs in header to h.

func (*Header) Clone

func (h *Header) Clone() *Header

Clone returns a deep copy of a Header.

func (*Header) Contains

func (h *Header) Contains(key string) (value string, ok bool)

Contains gets the first value associated with the given key, and also returns a bool indicating whether the header entry exists.

If there are no values associated with the key, Get returns "" for the value, and ok is false.

func (*Header) ContainsKey

func (h *Header) ContainsKey(key string) bool

Contains Key

func (*Header) ContentLength

func (h *Header) ContentLength() (value int, ok bool, err error)

ContentLength returns the value of the "content-length" header entry. If the "content-length" header is missing, then ok is false. If the "content-length" entry is present but is not a valid non-negative integer then err is non-nil.

func (*Header) Del

func (h *Header) Del(key string)

Del deletes all header entries with the specified key.

func (*Header) Get

func (h *Header) Get(key string) string

Get gets the first value associated with the given key. If there are no values associated with the key, Get returns "".

func (*Header) GetAll

func (h *Header) GetAll(key string) []string

GetAll returns all of the values associated with a given key. Normally there is only one header entry per key, but it is permitted to have multiple entries according to the STOMP standard.

func (*Header) GetAt

func (h *Header) GetAt(index int) (key, value string)

Returns the header name and value at the specified index in the collection. The index should be in the range 0 <= index < Len(), a panic will occur if it is outside this range.

func (*Header) Len

func (h *Header) Len() int

Len returns the number of header entries in the header.

func (*Header) Set

func (h *Header) Set(key, value string)

Set replaces the value of any existing header entry with the specified key. If there is no existing header entry with the specified key, a new header entry is added.

type Reader

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

The Reader type reads STOMP frames from an underlying io.Reader. The reader is buffered, and the size of the buffer is the maximum size permitted for the STOMP frame command and header section. A STOMP frame is rejected if its command and header section exceed the buffer size.

func NewReader

func NewReader(reader io.Reader) *Reader

NewReader creates a Reader with the default underlying buffer size.

func NewReaderSize

func NewReaderSize(reader io.Reader, bufferSize int) *Reader

NewReaderSize creates a Reader with an underlying bufferSize of the specified size.

func (*Reader) Read

func (r *Reader) Read() (*Frame, error)

Read a STOMP frame from the input. If the input contains one or more heart-beat characters and no frame, then nil will be returned for the frame. Calling programs should always check for a nil frame.

type StompManager

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

func (*StompManager) AddSubscribeDestination

func (manager *StompManager) AddSubscribeDestination(destinations ...string)

func (*StompManager) LetStompUnitSend

func (manager *StompManager) LetStompUnitSend(stompMessageFrame *Frame, unitSessionId string)
指定StompUnit.SessionId查找StompUnit发送stompFrame

LetStompUnitSend 指定StompUnit.SessionId查找StompUnit发送stompFrame

 参数:
	stompMessageFrame	*Frame	指定的Stomp数据包
	unitSessionId		string	指定的StompUnit的SessionId

func (*StompManager) NewMessageId

func (manager *StompManager) NewMessageId() string

func (*StompManager) Publish

func (manager *StompManager) Publish(stompMessageFrame *Frame)

用来发布订阅的内容.

func (*StompManager) RegistDestinationToApplication

func (manager *StompManager) RegistDestinationToApplication(destinationRoots ...string)

func (*StompManager) RegistDestinationToBroadcastAll

func (manager *StompManager) RegistDestinationToBroadcastAll(destinationRoots ...string)

群发路径注册

func (*StompManager) RegistDestinationToUser

func (manager *StompManager) RegistDestinationToUser(destinationRoots ...string)

func (*StompManager) StompUnitOnClose

func (manager *StompManager) StompUnitOnClose(stompUnit *StompUnit)

when stompBehavior closing,need remove subscribe

func (*StompManager) SubScribe

func (manager *StompManager) SubScribe(subScribeFrame *Frame, stompUnit *StompUnit) *Frame

SubScribe 添加一个新的订阅地址 参数:

subScribeFrame	客户端的订阅数据包
stompUnit		客户端连接对象

return nil:Success, not NULL:ERROR

func (*StompManager) SubscribeFlowDirction

func (manager *StompManager) SubscribeFlowDirction(destination string) int

func (*StompManager) UnSubScribe

func (manager *StompManager) UnSubScribe(unSubScribeFrame *Frame, stompUnit *StompUnit)

/ 客户端取消订阅

type StompUnit

type StompUnit struct {
	SessionId                 string            // 使用UUID分配id
	TopicSubidDictionary      map[string]string // 按照订阅地址关联Stomp客户端连接,key:Destination  Value:Sub-id
	TopicSubidDictionaryMutex *sync.Mutex       // 锁
	IsConnected               bool              // 是否建立stomp连接,更改前,需要建立connect
	PublishManager            *StompManager     // 主服务的管理,类似服务的管家

	ControllerUnitId string // 登录时使用,用来保持连接的
	// contains filtered or unexported fields
}

func NewStompUnit

func NewStompUnit(connection *websocket.Conn, publishManager *StompManager, reflexHandle func(sourceStompMessage *Frame, unit *StompUnit)) StompUnit

NestompserverUnit 创建一个Tcp连接单元

func (*StompUnit) IsUser

func (stompUnit *StompUnit) IsUser() bool

func (*StompUnit) Run

func (stompUnit *StompUnit) Run()

Run 执行工作

func (*StompUnit) SendStompMessage

func (stompUnit *StompUnit) SendStompMessage(stompMessageFrame *Frame)

type Writer

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

Writes STOMP frames to an underlying io.Writer.

func NewWriter

func NewWriter(writer io.Writer) *Writer

Creates a new Writer object, which writes to an underlying io.Writer.

func NewWriterSize

func NewWriterSize(writer io.Writer, bufferSize int) *Writer

func (*Writer) Write

func (w *Writer) Write(f *Frame) error

Write the contents of a frame to the underlying io.Writer.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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