Documentation ¶
Index ¶
Constants ¶
const ( NewUserMsg messageType = iota RemoveUserMsg RenameUserMsg NewFileMsg RemoveFileMsg InitMsg ChatMsg SignalingMsg UploadProgressMsg )
those are the message types passed between server/client through websocket or HTTP req/res
const (
PageIdLength = 6 + 18 // 6 for 36-based int64 value of timestamp, 18 for random alpha-numeric string
)
Variables ¶
This section is empty.
Functions ¶
Types ¶
type FileNamer ¶
type FileNamer interface {
// contains filtered or unexported methods
}
Each file has a fileID, which can be a random string, or hashing result of its content. This type must implement name() function returning a string as fileID.
type FileUploadProgress ¶
type FileUploadProgress struct { FileId fileId `json:"fileId"` FileSize int64 `json:"-"` // this is not the real filesize but request.ContentLength which include other overhead(multipart boundary string, fieldName/fieldValue) UploadedBytes int64 `json:"-"` MIME string `json:"MIME,omitempty"` // when upload succeeded(progress hits 1), server pass this field with the new value detected by http.DetectContentType Progress float32 `json:"progress"` // contains filtered or unexported fields }
FileUploadProgress is a io.Writer, passed to io.Copy() when client is uploading a file, it serves 2 purposes: to calculate the uploaded bytes(return error if exceeded maximum allowed filesize), to broadcast the progress value to all clients
type Page ¶
type Page struct { Id pageId `bson:"pageId" json:"pageId"` Users []*User `bson:"-" json:"-"` // when marshaling, skip Users field, otherwise infinite loop would occur: Page has users, which has page, which has user, ... Files []*File `bson:"files" json:"-"` ExpiresAt time.Time `bson:"expiresAt" json:"expiresAt"` // contains filtered or unexported fields }
func NewPage ¶
func NewPage(pid pageId) *Page
NewPage returns a *Page object, it only get called in pagemanager.handleUserJoin() when a new user(connect via websocket) want to join a page, and pagemanager found the page doesn't exist yet, thus create the page.
func (*Page) AddUser ¶
AddUser add the user into current page object after successfully sending the initMsg(user profile, peerList, fileList, etc)
func (*Page) HandleUpload ¶
HandleUpload use reader.NextPart() to read the file data wrapped in multi-part request format. The request only has 2 part: fileId and actual file data. When saving the file data, it use io.TeeReader to call FileUploadProgress.Write() to calculate uploaded bytes and broadcast the progress to all peers.
func (*Page) RemoveUser ¶
RemoveUser remove the user from current page. The returned boolean value indicates whether this is the last user and there is no incoming new user. In other word, is it safe also to remove the page from the page manager object?
type SignalingData ¶
type SignalingData struct { MsgType string `json:"msgType"` From string `json:"from"` To string `json:"to"` SignalingData interface{} `json:"signalingData"` }
simple-filer need this data to be exchanged between 2 peers before they can talk to each other directly
type User ¶
type User struct { Id userId `json:"id"` Name string `json:"name"` Page *Page `json:"-"` // when marshaling, skip Page field, otherwise, infinite loop would occur. User has page, which has users, which has page, .... Socket *websocket.Conn `json:"-"` PeerMsg chan *Message `json:"-"` }
func NewUser ¶
NewUser is invoked when socket connection is successfully created, and returns a user object. This object requires a *Page field(we pass a dummy &Page{Id: pid} object. At this moment, we don't know whether this Page object exists in fileManager or not. Caller will send the user object to pagemanager.handleUserJoin(userObj) pageManager will decide whether to use the existing page object or create a new one based on pageId.