Backend chat server based on the Websocket written by Go.
Installing go-chat requires Go 1.9 or newer, and dep command.
You can download go-chat
and its dependencies with go
and dep
commands:
$ go get -u github.com/shirasudon/go-chat
$ cd $GOPATH/src/github.com/shirasudon/go-chat
$ dep ensure
To start stand-alone local server, run the followings:
$ go run main/main.go
go-chat server uses the external configuration file, config.toml
.
If the configuration file is not found, use default values instead of that.
See below for the configuration values.
Example of config.toml
is located at infra/config/example/config.toml
.
The server can accept environment variable GOCHAT_CONFIG_FILE
which
specifies the configuration file to be used.
e.g. GOCHAT_CONFIG_FILE="another.toml" go run main/main.go
will use
another.toml
as configuration file.
- Configuration
// Configuration for server behavior.
type Config struct {
// HTTP service address for the server.
// The format is `[host]:[port]`, e.g. localhost:8080.
HTTP string
// Prefix of URI for the chat API.
// e.g. given ChatAPIPrefix = `/api` and chat API `/chat/rooms`,
// the prefixed chat API is `/api/chat/rooms`.
ChatAPIPrefix string
// Prefix of URI for the static file server.
//
// Example: given local html file `/www/index.html`,
// StaticHandlerPrefix = "/www" and StaticHandlerPrefix = "/static",
// the requesting the server with URI `/static/index.html` responds
// the html content of `/www/index.html`.
StaticHandlerPrefix string
// root directory to serve static files.
StaticFileDir string
// indicates whether serving static files is enable.
// if false, StaticHandlerPrefix and StaticFileDir do not
// affect the server.
EnableServeStaticFile bool
// show all of URI routes at server starts.
ShowRoutes bool
}
- Default Configuration
// DefaultConfig is default configuration for the server.
var DefaultConfig = Config{
HTTP: "localhost:8080",
ChatAPIPrefix: "",
StaticHandlerPrefix: "",
StaticFileDir: "", // current directory
EnableServeStaticFile: true,
ShowRoutes: true,
}
The server can accepts the Websocket connetion at /chat/ws
.
The Websocket connetion can be used two ways:
- Receive events from the server.
- Send actions to the server.
The Websocket connetion can be used as the Event stream which publish the Events, such as Message created, Message deleted and so on, to the client. The client can subscribe such events.
The event format is a JSON like:
{
"event": "<event name>",
"data": {
xxx,
yyy
}
}
The Websocket connetion can be used as the chat application interface for sending the commands, such as Post new message, Create new room and so on, to the server.
The action format is a JSON like:
{
"action": "<action name>",
"data": {
xxx,
yyy
}
}
Note that the responses to those commands are indirectly returnd by the events.
It login to the chat application. The login session is stored to the cookie.
User should login first and use cookie to access chat API.
Request JSON:
{
"name": "user name",
"password": "password",
"remember_me": true or false,
}
Response JSON:
{
"logged_in": true or false,
"remember_me": true or false,
"user_id": <logged-in user ID>, // number
"error": "error message if any",
}
It gets current login state.
Request JSON: None
Response JSON:
{
"logged_in": true or false,
"remember_me": true or false,
"user_id": <logged-in user ID>, // number
"error": "error message if any",
}
It logout from the chat application.
Request JSON: None
Response JSON:
{
"logged_in": false,
"error": "error message if any",
}
It creates new chat room.
Request JSON:
{
"room_name": "<room_name>",
"room_member_ids": [1,2, ...],
}
response JSON:
{
"room_id": created_room_id,
"ok": true,
}
It deletes existance chat room specified by room_id
.
Request JSON: None
.
response JSON:
{
"room_id": deleted_room_id,
"ok": true,
}
It returns user information specified by user_id
.
Request JSON: None
.
response JSON:
{
"user_id": user_id,
"user_name": "<user name>",
"first_name": "<first name>",
"last_name": "<last name>",
"friends": [
{
"user_id": user_id,
"user_name": "<user name>",
"first_name": "<first name>",
"last_name": "<last name>",
},
{
...
}
],
"rooms": [
{
"room_id": room_id,
"room_name": "<room name>",
},
{
...
}
]
}
It returns room information specified by room_id
.
Request JSON: None
.
response JSON:
{
"room_id": room_id,
"room_name": "<room name>",
"room_creator_id": room_creator_id, // user_id
"room_members": [
{
"user_id": user_id,
"user_name": "<user name>",
"first_name": "<first name>",
"last_name": "<last name>",
"message_read_at", message_read_time,
},
{
...
}
],
"room_members_size": room_members_size,
}
It returns messages in the room specified by room_id
.
The returned messages contains both read and unread messages.
Query Paramters:
before
: The start point of thecreated_at
in result messages. It must be RFC3339 form.limit
: The number of result messages.
Request JSON:
{
"before": "time with RFC3339 format",
"limit": limit_number,
}
response JSON:
{
"room_id": room_id,
"messages": [
{
"message_id": message_id,
"content": "<message content>",
"created_at": created_at,
},
...
],
"messages_size": messages_size,
}
Example:
GET /chat/rooms/:room_id/messages?before=2018-01-01T12:34:56Z?limit=10
will returns
queried result which contains 10 messages and all of these are created before 2018/01/01 12:34:56.
It returns messages unread by the logged-in user in the room specified by room_id
.
Query Paramters:
limit
: The number of result messages.
Request JSON:
{
"limit": limit_number,
}
response JSON:
{
"room_id": room_id,
"messages": [
{
"message_id": message_id,
"content": "<message content>",
"created_at": created_at,
},
...
],
"messages_size": messages_size,
}
Example:
GET /chat/rooms/:room_id/messages/unread?limit=10
will returns queried result which contains 10 messages.
It notifies to the server that the messages in the room specified by the room_id
are
read by the user.
Request JSON:
{
"read_at": <messages read time> // time format
}
response JSON:
{
"updated_room_id": room_id,
"read_user_id": user_id,
"ok": true or false,
}