mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 10:41:03 +01:00
update websocket examples - keep neffos and use the iris/websocket as helper only
Former-commit-id: c34b916e186286cd0de6d694d8bdb4f9390121a2
This commit is contained in:
parent
69171e844d
commit
35389c6ef8
|
@ -477,7 +477,9 @@ iris session manager lives on its own [package](https://github.com/kataras/iris/
|
|||
|
||||
### Websockets
|
||||
|
||||
iris websocket library lives on its own [package](https://github.com/kataras/iris/tree/master/websocket) which depends on the [kataras/neffos](https://github.com/kataras/neffos) external package.
|
||||
[WebSocket](https://wikipedia.org/wiki/WebSocket) is a protocol that enables two-way persistent communication channels over TCP connections. It is used for applications such as chat, stock tickers, games, anywhere you want real-time functionality in a web application.
|
||||
|
||||
Iris websocket library is now merged with the [neffos real-time framework](https://github.com/kataras/neffos) and Iris-specific helpers live on the [iris/websocket](https://github.com/kataras/iris/tree/master/websocket) subpackage. Learn neffos from its [wiki](https://github.com/kataras/neffos#learning-neffos) and have a look some of the [Iris websocket examples](websocket/).
|
||||
|
||||
The package is designed to work with raw websockets although its API is similar to the famous [socket.io](https://socket.io). I have read an article recently and I felt very contented about my decision to design a **fast** websocket-**only** package for Iris and not a backwards socket.io-like package. You can read that article by following this link: https://medium.com/@ivanderbyl/why-you-don-t-need-socket-io-6848f1c871cd.
|
||||
|
||||
|
@ -486,13 +488,8 @@ The package is designed to work with raw websockets although its API is similar
|
|||
* [Go Client](websocket/basic/go-client/client.go)
|
||||
* [Browser Client](websocket/basic/browser/index.html)
|
||||
* [Browser NPM Client (browserify)](websocket/basic/browserify/app.js)
|
||||
- [Native Messages](websocket/native-messages/main.go)
|
||||
- [Connection List](websocket/connectionlist/main.go)
|
||||
- [TLS Enabled](websocket/secure/main.go)
|
||||
- [Custom Raw Go Client](websocket/custom-go-client/main.go)
|
||||
- [Third-Party socket.io](websocket/third-party-socketio/main.go)
|
||||
|
||||
> You're free to use your own favourite websockets package if you'd like so.
|
||||
- [Native Messages](websocket/native-messages/main.go) **UPDATED**
|
||||
- [TLS Enabled](websocket/secure/README.md)
|
||||
|
||||
### Typescript Automation Tools
|
||||
|
||||
|
|
|
@ -425,23 +425,13 @@ Iris session 管理独立包 [package](https://github.com/kataras/iris/tree/mast
|
|||
|
||||
### Websockets
|
||||
|
||||
iris websocket库依赖于它自己的[包](https://github.com/kataras/iris/tree/master/websocket).
|
||||
|
||||
设计这个包的目的是处理原始websockets,虽然它的API和著名的[socket.io](https://socket.io)很像。我最近读了一片文章,并且对我
|
||||
决定给iris设计一个**快速的**websocket**限定**包并且不是一个向后传递类socket.io的包。你可以阅读这个链接里的文章https://medium.com/@ivanderbyl/why-you-don-t-need-socket-io-6848f1c871cd。
|
||||
|
||||
- [Basic](websocket/basic) **新**
|
||||
* [Server](websocket/basic/server.go)
|
||||
* [Go Client](websocket/basic/go-client/client.go)
|
||||
* [Browser Client](websocket/basic/browser/index.html)
|
||||
* [Browser NPM Client (browserify)](websocket/basic/browserify/app.js)
|
||||
- [原生消息](websocket/native-messages/main.go)
|
||||
- [连接列表](websocket/connectionlist/main.go)
|
||||
- [TLS支持](websocket/secure/main.go)
|
||||
- [自定义原始Go客户端](websocket/custom-go-client/main.go)
|
||||
- [第三方socket.io](websocket/third-party-socketio/main.go)
|
||||
|
||||
> 如果你愿意,你可以自由使用你自己喜欢的websockets包。
|
||||
- [原生消息](websocket/native-messages/main.go) **更新**
|
||||
- [TLS支持](websocket/secure/README.md)
|
||||
|
||||
### Typescript 自动化工具
|
||||
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
# Websocket
|
||||
|
||||
[WebSocket](https://wikipedia.org/wiki/WebSocket) is a protocol that enables two-way persistent communication channels over TCP connections. It is used for applications such as chat, stock tickers, games, anywhere you want real-time functionality in a web application.
|
||||
|
||||
[View or download sample code](https://github.com/kataras/iris/tree/master/_examples/websocket).
|
||||
|
||||
## When to use it
|
||||
|
||||
Use WebSockets when you need to work directly with a socket connection. For example, you might need the best possible performance for a real-time game.
|
||||
|
||||
## How to use it
|
||||
|
||||
* import the `"github.com/kataras/iris/websocket"`
|
||||
* Configure the websocket package.
|
||||
* Accept WebSocket requests.
|
||||
* Send and receive messages.
|
||||
|
||||
### Import the websocket package
|
||||
|
||||
```go
|
||||
import "github.com/kataras/iris/websocket"
|
||||
```
|
||||
|
||||
### Configure the websocket package
|
||||
|
||||
```go
|
||||
import "github.com/kataras/iris/websocket"
|
||||
|
||||
func main() {
|
||||
ws := websocket.New(websocket.Config{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
#### Complete configuration
|
||||
|
||||
```go
|
||||
// Config the websocket server configuration
|
||||
// all of these are optional.
|
||||
type Config struct {
|
||||
// IDGenerator used to create (and later on, set)
|
||||
// an ID for each incoming websocket connections (clients).
|
||||
// The request is an argument which you can use to generate the ID (from headers for example).
|
||||
// If empty then the ID is generated by DefaultIDGenerator: randomString(64)
|
||||
IDGenerator func(ctx context.Context) string
|
||||
// Error is the function that will be fired if any client couldn't upgrade the HTTP connection
|
||||
// to a websocket connection, a handshake error.
|
||||
Error func(w http.ResponseWriter, r *http.Request, status int, reason error)
|
||||
// CheckOrigin a function that is called right before the handshake,
|
||||
// if returns false then that client is not allowed to connect with the websocket server.
|
||||
CheckOrigin func(r *http.Request) bool
|
||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||
HandshakeTimeout time.Duration
|
||||
// WriteTimeout time allowed to write a message to the connection.
|
||||
// 0 means no timeout.
|
||||
// Default value is 0
|
||||
WriteTimeout time.Duration
|
||||
// ReadTimeout time allowed to read a message from the connection.
|
||||
// 0 means no timeout.
|
||||
// Default value is 0
|
||||
ReadTimeout time.Duration
|
||||
// PongTimeout allowed to read the next pong message from the connection.
|
||||
// Default value is 60 * time.Second
|
||||
PongTimeout time.Duration
|
||||
// PingPeriod send ping messages to the connection with this period. Must be less than PongTimeout.
|
||||
// Default value is 60 *time.Second
|
||||
PingPeriod time.Duration
|
||||
// MaxMessageSize max message size allowed from connection.
|
||||
// Default value is 1024
|
||||
MaxMessageSize int64
|
||||
// BinaryMessages set it to true in order to denotes binary data messages instead of utf-8 text
|
||||
// compatible if you wanna use the Connection's EmitMessage to send a custom binary data to the client, like a native server-client communication.
|
||||
// defaults to false
|
||||
BinaryMessages bool
|
||||
// ReadBufferSize is the buffer size for the underline reader
|
||||
// Default value is 4096
|
||||
ReadBufferSize int
|
||||
// WriteBufferSize is the buffer size for the underline writer
|
||||
// Default value is 4096
|
||||
WriteBufferSize int
|
||||
// EnableCompression specify if the server should attempt to negotiate per
|
||||
// message compression (RFC 7692). Setting this value to true does not
|
||||
// guarantee that compression will be supported. Currently only "no context
|
||||
// takeover" modes are supported.
|
||||
EnableCompression bool
|
||||
|
||||
// Subprotocols specifies the server's supported protocols in order of
|
||||
// preference. If this field is set, then the Upgrade method negotiates a
|
||||
// subprotocol by selecting the first match in this list with a protocol
|
||||
// requested by the client.
|
||||
Subprotocols []string
|
||||
}
|
||||
```
|
||||
|
||||
### Accept WebSocket requests & send & receive messages
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/websocket"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ws := websocket.New(websocket.Config{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
})
|
||||
|
||||
ws.OnConnection(handleConnection)
|
||||
|
||||
app := iris.New()
|
||||
// register the server on an endpoint.
|
||||
// see the inline javascript code in the websockets.html, this endpoint is used to connect to the server.
|
||||
app.Get("/echo", ws.Handler())
|
||||
|
||||
// serve the javascript builtin client-side library,
|
||||
// see websockets.html script tags, this path is used.
|
||||
app.Any("/iris-ws.js", func(ctx iris.Context) {
|
||||
ctx.Write(websocket.ClientSource)
|
||||
})
|
||||
}
|
||||
|
||||
func handleConnection(c websocket.Connection) {
|
||||
// Read events from browser
|
||||
c.On("chat", func(msg string) {
|
||||
// Print the message to the console, c.Context() is the iris's http context.
|
||||
fmt.Printf("%s sent: %s\n", c.Context().RemoteAddr(), msg)
|
||||
// Write message back to the client message owner:
|
||||
// c.Emit("chat", msg)
|
||||
c.To(websocket.Broadcast).Emit("chat", msg)
|
||||
})
|
||||
}
|
||||
```
|
|
@ -10,6 +10,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/kataras/iris/websocket"
|
||||
|
||||
"github.com/kataras/neffos"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -21,17 +23,17 @@ const (
|
|||
// this can be shared with the server.go's.
|
||||
// `NSConn.Conn` has the `IsClient() bool` method which can be used to
|
||||
// check if that's is a client or a server-side callback.
|
||||
var clientEvents = websocket.Namespaces{
|
||||
namespace: websocket.Events{
|
||||
websocket.OnNamespaceConnected: func(c *websocket.NSConn, msg websocket.Message) error {
|
||||
var clientEvents = neffos.Namespaces{
|
||||
namespace: neffos.Events{
|
||||
neffos.OnNamespaceConnected: func(c *neffos.NSConn, msg neffos.Message) error {
|
||||
log.Printf("connected to namespace: %s", msg.Namespace)
|
||||
return nil
|
||||
},
|
||||
websocket.OnNamespaceDisconnect: func(c *websocket.NSConn, msg websocket.Message) error {
|
||||
neffos.OnNamespaceDisconnect: func(c *neffos.NSConn, msg neffos.Message) error {
|
||||
log.Printf("disconnected from namespace: %s", msg.Namespace)
|
||||
return nil
|
||||
},
|
||||
"chat": func(c *websocket.NSConn, msg websocket.Message) error {
|
||||
"chat": func(c *neffos.NSConn, msg neffos.Message) error {
|
||||
log.Printf("%s", string(msg.Body))
|
||||
return nil
|
||||
},
|
||||
|
@ -42,7 +44,7 @@ func main() {
|
|||
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(dialAndConnectTimeout))
|
||||
defer cancel()
|
||||
|
||||
client, err := websocket.Dial(ctx, websocket.DefaultGorillaDialer, endpoint, clientEvents)
|
||||
client, err := neffos.Dial(ctx, websocket.DefaultGorillaDialer, endpoint, clientEvents)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -5,26 +5,29 @@ import (
|
|||
|
||||
"github.com/kataras/iris"
|
||||
"github.com/kataras/iris/websocket"
|
||||
|
||||
"github.com/kataras/neffos"
|
||||
)
|
||||
|
||||
const namespace = "default"
|
||||
|
||||
// if namespace is empty then simply websocket.Events{...} can be used instead.
|
||||
var serverEvents = websocket.Namespaces{
|
||||
namespace: websocket.Events{
|
||||
websocket.OnNamespaceConnected: func(nsConn *websocket.NSConn, msg websocket.Message) error {
|
||||
// if namespace is empty then simply neffos.Events{...} can be used instead.
|
||||
var serverEvents = neffos.Namespaces{
|
||||
namespace: neffos.Events{
|
||||
neffos.OnNamespaceConnected: func(nsConn *neffos.NSConn, msg neffos.Message) error {
|
||||
// with `websocket.GetContext` you can retrieve the Iris' `Context`.
|
||||
ctx := websocket.GetContext(nsConn.Conn)
|
||||
|
||||
log.Printf("[%s] connected to namespace [%s] with IP [%s]",
|
||||
nsConn, msg.Namespace,
|
||||
// with `GetContext` you can retrieve the Iris' `Context`, alternatively
|
||||
// you can use the `nsConn.Conn.Socket().Request()` to get the raw `*http.Request`.
|
||||
websocket.GetContext(nsConn.Conn).RemoteAddr())
|
||||
ctx.RemoteAddr())
|
||||
return nil
|
||||
},
|
||||
websocket.OnNamespaceDisconnect: func(nsConn *websocket.NSConn, msg websocket.Message) error {
|
||||
neffos.OnNamespaceDisconnect: func(nsConn *neffos.NSConn, msg neffos.Message) error {
|
||||
log.Printf("[%s] disconnected from namespace [%s]", nsConn, msg.Namespace)
|
||||
return nil
|
||||
},
|
||||
"chat": func(nsConn *websocket.NSConn, msg websocket.Message) error {
|
||||
"chat": func(nsConn *neffos.NSConn, msg neffos.Message) error {
|
||||
// room.String() returns -> NSConn.String() returns -> Conn.String() returns -> Conn.ID()
|
||||
log.Printf("[%s] sent: %s", nsConn, string(msg.Body))
|
||||
|
||||
|
@ -39,7 +42,7 @@ var serverEvents = websocket.Namespaces{
|
|||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
websocketServer := websocket.New(
|
||||
websocketServer := neffos.New(
|
||||
websocket.DefaultGorillaUpgrader, /* DefaultGobwasUpgrader can be used too. */
|
||||
serverEvents)
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/kataras/iris/websocket"
|
||||
|
||||
"github.com/kataras/neffos"
|
||||
)
|
||||
|
||||
type clientPage struct {
|
||||
|
@ -25,8 +26,8 @@ func main() {
|
|||
// and contains only one registered event which is the `OnNativeMessage`.
|
||||
// When `Events{...}` is used instead of `Namespaces{ "namespaceName": Events{...}}`
|
||||
// then the namespace is empty "".
|
||||
ws := websocket.New(websocket.DefaultGorillaUpgrader, websocket.Events{
|
||||
websocket.OnNativeMessage: func(nsConn *websocket.NSConn, msg websocket.Message) error {
|
||||
ws := neffos.New(websocket.DefaultGorillaUpgrader, neffos.Events{
|
||||
neffos.OnNativeMessage: func(nsConn *neffos.NSConn, msg neffos.Message) error {
|
||||
log.Printf("Server got: %s from [%s]", msg.Body, nsConn.Conn.ID())
|
||||
|
||||
nsConn.Conn.Server().Broadcast(nsConn, msg)
|
||||
|
@ -34,12 +35,12 @@ func main() {
|
|||
},
|
||||
})
|
||||
|
||||
ws.OnConnect = func(c *websocket.Conn) error {
|
||||
ws.OnConnect = func(c *neffos.Conn) error {
|
||||
log.Printf("[%s] Connected to server!", c.ID())
|
||||
return nil
|
||||
}
|
||||
|
||||
ws.OnDisconnect = func(c *websocket.Conn) {
|
||||
ws.OnDisconnect = func(c *neffos.Conn) {
|
||||
log.Printf("[%s] Disconnected from server", c.ID())
|
||||
}
|
||||
|
||||
|
|
6
_examples/websocket/secure/README.md
Normal file
6
_examples/websocket/secure/README.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Secure Websockets
|
||||
|
||||
1. Run your server through `https://` (`iris.Run(iris.TLS)` or `iris.Run(iris.AutoTLS)` or a custom `iris.Listener(...)`)
|
||||
2. Nothing changes inside the whole app, including the websocket side
|
||||
3. The clients must dial the websocket server endpoint (i.e `/echo`) via `wss://` prefix (instead of the non-secure `ws://`), for example `wss://example.com/echo`
|
||||
4. Ready to GO.
|
|
@ -1,174 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/kataras/iris/websocket"
|
||||
)
|
||||
|
||||
type clientPage struct {
|
||||
Title string
|
||||
Host string
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.RegisterView(iris.HTML("./templates", ".html")) // select the html engine to serve templates
|
||||
|
||||
ws := websocket.New(websocket.Config{})
|
||||
|
||||
// register the server on an endpoint.
|
||||
// see the inline javascript code i the websockets.html, this endpoint is used to connect to the server.
|
||||
app.Get("/my_endpoint", ws.Handler())
|
||||
|
||||
// serve the javascript builtin client-side library,
|
||||
// see websockets.html script tags, this path is used.
|
||||
app.Any("/iris-ws.js", func(ctx iris.Context) {
|
||||
ctx.Write(websocket.ClientSource)
|
||||
})
|
||||
|
||||
app.HandleDir("/js", "./static/js")
|
||||
app.Get("/", func(ctx iris.Context) {
|
||||
// send our custom javascript source file before client really asks for that
|
||||
// using the go v1.8's HTTP/2 Push.
|
||||
// Note that you have to listen using ListenTLS in order this to work.
|
||||
if err := ctx.ResponseWriter().Push("/js/chat.js", nil); err != nil {
|
||||
ctx.Application().Logger().Warn(err.Error())
|
||||
}
|
||||
ctx.ViewData("", clientPage{"Client Page", ctx.Host()})
|
||||
ctx.View("client.html")
|
||||
})
|
||||
|
||||
var myChatRoom = "room1"
|
||||
|
||||
ws.OnConnection(func(c websocket.Connection) {
|
||||
// Context returns the (upgraded) iris.Context of this connection
|
||||
// avoid using it, you normally don't need it,
|
||||
// websocket has everything you need to authenticate the user BUT if it's necessary
|
||||
// then you use it to receive user information, for example: from headers.
|
||||
|
||||
// ctx := c.Context()
|
||||
|
||||
// join to a room (optional)
|
||||
c.Join(myChatRoom)
|
||||
|
||||
c.On("chat", func(message string) {
|
||||
if message == "leave" {
|
||||
c.Leave(myChatRoom)
|
||||
c.To(myChatRoom).Emit("chat", "Client with ID: "+c.ID()+" left from the room and cannot send or receive message to/from this room.")
|
||||
c.Emit("chat", "You have left from the room: "+myChatRoom+" you cannot send or receive any messages from others inside that room.")
|
||||
return
|
||||
}
|
||||
// to all except this connection ->
|
||||
// c.To(websocket.Broadcast).Emit("chat", "Message from: "+c.ID()+"-> "+message)
|
||||
// to all connected clients: c.To(websocket.All)
|
||||
|
||||
// to the client itself ->
|
||||
//c.Emit("chat", "Message from myself: "+message)
|
||||
|
||||
//send the message to the whole room,
|
||||
//all connections are inside this room will receive this message
|
||||
c.To(myChatRoom).Emit("chat", "From: "+c.ID()+": "+message)
|
||||
})
|
||||
|
||||
// or create a new leave event
|
||||
// c.On("leave", func() {
|
||||
// c.Leave(myChatRoom)
|
||||
// })
|
||||
|
||||
c.OnDisconnect(func() {
|
||||
fmt.Printf("Connection with ID: %s has been disconnected!\n", c.ID())
|
||||
})
|
||||
})
|
||||
|
||||
listenTLS(app)
|
||||
|
||||
}
|
||||
|
||||
// a test listenTLS for our localhost
|
||||
func listenTLS(app *iris.Application) {
|
||||
|
||||
const (
|
||||
testTLSCert = `-----BEGIN CERTIFICATE-----
|
||||
MIIDBTCCAe2gAwIBAgIJAOYzROngkH6NMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
|
||||
BAMMDmxvY2FsaG9zdDo4MDgwMB4XDTE3MDIxNzAzNDM1NFoXDTI3MDIxNTAzNDM1
|
||||
NFowGTEXMBUGA1UEAwwObG9jYWxob3N0OjgwODAwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQCfsiVHO14FpKsi0pvBv68oApQm2MO+dCvq87sDU4E0QJhG
|
||||
KV1RCUmQVypChEqdLlUQsopcXSyKwbWoyg1/KNHYO3DHMfePb4bC1UD2HENq7Ph2
|
||||
8QJTEi/CJvUB9hqke/YCoWYdjFiI3h3Hw8q5whGO5XR3R23z69vr5XxoNlcF2R+O
|
||||
TdkzArd0CWTZS27vbgdnyi9v3Waydh/rl+QRtPUgEoCEqOOkMSMldXO6Z9GlUk9b
|
||||
FQHwIuEnlSoVFB5ot5cqebEjJnWMLLP83KOCQekJeHZOyjeTe8W0Fy1DGu5fvFNh
|
||||
xde9e/7XlFE//00vT7nBmJAUV/2CXC8U5lsjLEqdAgMBAAGjUDBOMB0GA1UdDgQW
|
||||
BBQOfENuLn/t0Z4ZY1+RPWaz7RBH+TAfBgNVHSMEGDAWgBQOfENuLn/t0Z4ZY1+R
|
||||
PWaz7RBH+TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBG7AEEuIq6
|
||||
rWCE5I2t4IXz0jN7MilqEhUWDbUajl1paYf6Ikx5QhMsFx21p6WEWYIYcnWAKZe2
|
||||
chAgnnGojuxdx0qjiaH4N4xWGHsWhaesnIF1xJepLlX3kJZQURvRxM4wlljlQPIb
|
||||
9tqzKP131K1HDqplAtp7nWQ72m3J0ZfzH0mYIUxuaS/uQIVtgKqdilwy/VE5dRZ9
|
||||
QFIb4G9TnNThXMqgTLjfNr33jVbTuv6fzKHYNbCkP3L10ydEs/ddlREmtsn9nE8Q
|
||||
XCTIYXzA2kr5kWk7d3LkUiSvu3g2S1Ol1YaIKaOQyRveseCGwR4xohLT+dPUW9dL
|
||||
3hDVLlwE3mB3
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
`
|
||||
testTLSKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAn7IlRzteBaSrItKbwb+vKAKUJtjDvnQr6vO7A1OBNECYRild
|
||||
UQlJkFcqQoRKnS5VELKKXF0sisG1qMoNfyjR2DtwxzH3j2+GwtVA9hxDauz4dvEC
|
||||
UxIvwib1AfYapHv2AqFmHYxYiN4dx8PKucIRjuV0d0dt8+vb6+V8aDZXBdkfjk3Z
|
||||
MwK3dAlk2Utu724HZ8ovb91msnYf65fkEbT1IBKAhKjjpDEjJXVzumfRpVJPWxUB
|
||||
8CLhJ5UqFRQeaLeXKnmxIyZ1jCyz/NyjgkHpCXh2Tso3k3vFtBctQxruX7xTYcXX
|
||||
vXv+15RRP/9NL0+5wZiQFFf9glwvFOZbIyxKnQIDAQABAoIBAEzBx4ExW8PCni8i
|
||||
o5LAm2PTuXniflMwa1uGwsCahmOjGI3AnAWzPRSPkNRf2a0q8+AOsMosTphy+umi
|
||||
FFKmQBZ6m35i2earaE6FSbABbbYbKGGi/ccH2sSrDOBgdfXRTzF8eiSBrJw8hnvZ
|
||||
87rNOLtCNnSOdJ7lItODfgRo+fLo4uQenJ8VONYwtwm1ejn8qLXq8O5zF66IYUD6
|
||||
gAzqOiAWumgZL0tEmndeQ+noe4STpJZlOjiCsA12NiJaKDDeDIn5A/pXce+bYNfJ
|
||||
k4yoroyq/JXBkhyuZDvX9vYp5AA+Q68h8/KmsKkifUgSGSHun5/80lYyT/f60TLX
|
||||
PxT9GYECgYEA0s8qck7L29nBBTQ6IPF3GHGmqiRdfH+qhP/Jn4NtoW3XuVe4A15i
|
||||
REq1L8WAiOUIBnBaD8HzbeioqJJYx1pu7x9h/GCNDhdBfwhTjnBe+JjfLqvJKnc0
|
||||
HUT5wj4DVqattxKzUW8kTRBSWtVremzeffDo+EL6dnR7Bc02Ibs4WpUCgYEAwe34
|
||||
Uqhie+/EFr4HjYRUNZSNgYNAJkKHVxk4qGzG5VhvjPafnHUbo+Kk/0QW7eIB+kvR
|
||||
FDO8oKh9wTBrWZEcLJP4jDIKh4y8hZTo9B8EjxFONXVxZlOSYuGjheL8AiLzE7L9
|
||||
C1spaKMM/MyxAXDRHpG/NeEgXM7Kn6kUGwJdNekCgYAshLNiEGHcu8+XWcAs1NFh
|
||||
yB56L9PORuerzpi1pvuv65JzAaNKktQNt/krbXoHbtaTBYb/bOYLf+aeMsmsz9w9
|
||||
g1MeCQXAxAiA2zFKE1D7Ds2S/ZQt8559z+MusgnicrCcyMY1nFL+M0QxCoD4CaWy
|
||||
0v1f8EUUXuTcBMo5tV/hQQKBgDoBBW8jsiFDu7DZscSgOde00QZVzZAkAfsJLisi
|
||||
LfNXGjZdZawUUuoX1iYLpZgNK25D0wtp1hdvjf2Ej/dAMd8bexHjvcaBT7ncqjiq
|
||||
NmDcWjofIIXspTIyLwjStXGmJnJT7N/CqoYDjtTmHGND7Shpi3mAFn/r0isjFUJm
|
||||
2J5RAoGALuGXxzmSRWmkIp11F/Qr3PBFWBWkrRWaH2TRLMhrU/wO8kCsSyo4PmAZ
|
||||
ltOfD7InpDiCu43hcDPQ/29FUbDnmAhvMnmIQuHXGgPF/LhqEhbKPA/o/eZdQVCK
|
||||
QG+tmveBBIYMed5YbWstZu/95lIHF+u8Hl+Z6xgveozfE5yqiUA=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
// create the key and cert files on the fly, and delete them when this test finished
|
||||
certFile, ferr := ioutil.TempFile("", "cert")
|
||||
|
||||
if ferr != nil {
|
||||
panic(ferr)
|
||||
}
|
||||
|
||||
keyFile, ferr := ioutil.TempFile("", "key")
|
||||
if ferr != nil {
|
||||
panic(ferr)
|
||||
}
|
||||
|
||||
certFile.WriteString(testTLSCert)
|
||||
keyFile.WriteString(testTLSKey)
|
||||
|
||||
// https://localhost
|
||||
app.Run(iris.TLS("localhost:443", certFile.Name(), keyFile.Name()))
|
||||
|
||||
certFile.Close()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
os.Remove(certFile.Name())
|
||||
|
||||
keyFile.Close()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
os.Remove(keyFile.Name())
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
var messageTxt;
|
||||
var messages;
|
||||
|
||||
$(function () {
|
||||
|
||||
messageTxt = $("#messageTxt");
|
||||
messages = $("#messages");
|
||||
|
||||
/* secure wss because we ListenTLS */
|
||||
w = new Ws("wss://" + HOST + "/my_endpoint");
|
||||
w.OnConnect(function () {
|
||||
console.log("Websocket connection established");
|
||||
});
|
||||
|
||||
w.OnDisconnect(function () {
|
||||
appendMessage($("<div><center><h3>Disconnected</h3></center></div>"));
|
||||
});
|
||||
|
||||
w.On("chat", function (message) {
|
||||
appendMessage($("<div>" + message + "</div>"));
|
||||
});
|
||||
|
||||
$("#sendBtn").click(function () {
|
||||
w.Emit("chat", messageTxt.val().toString());
|
||||
messageTxt.val("");
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
function appendMessage(messageDiv) {
|
||||
var theDiv = messages[0];
|
||||
var doScroll = theDiv.scrollTop == theDiv.scrollHeight - theDiv.clientHeight;
|
||||
messageDiv.appendTo(messages);
|
||||
if (doScroll) {
|
||||
theDiv.scrollTop = theDiv.scrollHeight - theDiv.clientHeight;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{ .Title}}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="messages"
|
||||
style="border-width: 1px; border-style: solid; height: 400px; width: 375px;">
|
||||
|
||||
</div>
|
||||
<input type="text" id="messageTxt" />
|
||||
<button type="button" id="sendBtn">Send</button>
|
||||
<script type="text/javascript">
|
||||
var HOST = {{.Host}}
|
||||
</script>
|
||||
<script src="/js/vendor/jquery-2.2.3.min.js"></script>
|
||||
<!-- This is auto-serving by the iris, you don't need to have this file in your disk-->
|
||||
<script src="/iris-ws.js"></script>
|
||||
<!-- -->
|
||||
<script src="/js/chat.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,44 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
|
||||
"github.com/googollee/go-socket.io"
|
||||
)
|
||||
|
||||
/*
|
||||
go get -u github.com/googollee/go-socket.io
|
||||
*/
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
server, err := socketio.NewServer(nil)
|
||||
if err != nil {
|
||||
app.Logger().Fatal(err)
|
||||
}
|
||||
|
||||
server.On("connection", func(so socketio.Socket) {
|
||||
app.Logger().Infof("on connection")
|
||||
so.Join("chat")
|
||||
so.On("chat message", func(msg string) {
|
||||
app.Logger().Infof("emit: %v", so.Emit("chat message", msg))
|
||||
so.BroadcastTo("chat", "chat message", msg)
|
||||
})
|
||||
so.On("disconnection", func() {
|
||||
app.Logger().Infof("on disconnect")
|
||||
})
|
||||
})
|
||||
|
||||
server.On("error", func(so socketio.Socket, err error) {
|
||||
app.Logger().Errorf("error: %v", err)
|
||||
})
|
||||
|
||||
// serve the socket.io endpoint.
|
||||
app.Any("/socket.io/{p:path}", iris.FromStd(server))
|
||||
|
||||
// serve the index.html and the javascript libraries at
|
||||
// http://localhost:8080
|
||||
app.HandleDir("/", "./public")
|
||||
|
||||
app.Run(iris.Addr("localhost:8080"), iris.WithoutPathCorrection)
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Socket.IO chat</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font: 13px Helvetica, Arial; }
|
||||
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
|
||||
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
|
||||
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
|
||||
#messages { list-style-type: none; margin: 0; padding: 0; }
|
||||
#messages li { padding: 5px 10px; }
|
||||
#messages li:nth-child(odd) { background: #eee; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul id="messages"></ul>
|
||||
<form action="">
|
||||
<input id="m" autocomplete="off" /><button>Send</button>
|
||||
</form>
|
||||
<script src="/socket.io-1.3.7.js"></script>
|
||||
<script src="/jquery-1.11.1.js"></script>
|
||||
<script>
|
||||
var socket = io();
|
||||
$('form').submit(function(){
|
||||
socket.emit('chat message with ack', $('#m').val(), function(data){
|
||||
$('#messages').append($('<li>').text('ACK CALLBACK: ' + data));
|
||||
});
|
||||
socket.emit('chat message', $('#m').val());
|
||||
$('#m').val('');
|
||||
return false;
|
||||
});
|
||||
socket.on('chat message', function(msg){
|
||||
$('#messages').append($('<li>').text(msg));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user