1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-11 05:55:57 +00:00

Add 'context.OnConnectionClose(callbackFn) bool' and 'context.OnClose(callbackFn)' and give a use case example. More on this path later on, stay tuned.

Former-commit-id: dc6580f072d076b8cb204a681e45905210981153
This commit is contained in:
Gerasimos (Makis) Maropoulos
2018-08-02 17:46:35 +03:00
parent d98da25ffb
commit 5d9ded37c4
9 changed files with 243 additions and 60 deletions

View File

@@ -6,6 +6,57 @@ This folder provides easy to understand code snippets on how to get started with
It doesn't always contain the "best ways" but it does cover each important feature that will make you so excited to GO with iris!
## Running the examples
1. Install the Go Programming Language, version 1.9+ from [here](https://golang.org/dl).
2. Install Iris: `go get -u github.com/kataras/iris`
3. Install any external packages that required by the examples
<details>
<summary>External packages</summary>
```bash
cd _examples && go get ./...
# or
go get github.com/iris-contrib/middleware/...
go get github.com/betacraft/yaag/irisyaag
go get github.com/markbates/goth/...
go get github.com/getsentry/raven-go/...
go get github.com/casbin/casbin
go get github.com/markbates/goth/...
go get github.com/aws/aws-sdk-go/...
go get github.com/getsentry/raven-go/...
go get github.com/casbin/casbin
go get github.com/aws/aws-sdk-go/...
go get github.com/prometheus/client_golang/...
go get github.com/didip/tollbooth
go get github.com/valyala/quicktemplate
go get github.com/shiyanhui/hero
go get github.com/go-xorm/xorm
go get github.com/nfnt/resize
go get github.com/prometheus/client_golang/...
go get github.com/didip/tollbooth
go get github.com/valyala/quicktemplate
go get github.com/shiyanhui/hero
go get github.com/go-xorm/xorm
go get github.com/nfnt/resize
go get github.com/dgrijalva/jwt-go
go get github.com/newrelic/go-agent
go get github.com/valyala/tcplisten
go get github.com/kataras/bindata/cmd/bindata
```
</details>
And execute
```sh
$ cd $GOPATH/src/github.com/kataras/iris/_examples/overview
$ go run main.go
```
> Test the examples by opening a terminal window and execute: `GOCACHE=off && cd _examples && go test -v ./...`
### Overview
- [Hello world!](hello-world/main.go)

View File

@@ -54,7 +54,7 @@ func (r resource) loadFromBase(dir string) string {
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
// result = strings.Replace(result, "\n", "\r\n", -1)
}
return result
}

View File

@@ -1,8 +1,8 @@
// Code generated by bindata. DO NOT EDIT.
// sources:
// assets\css\bootstrap.min.css
// assets\favicon.ico
// assets\js\jquery-2.1.1.js
// assets/css/bootstrap.min.css
// assets/favicon.ico
// assets/js/jquery-2.1.1.js
package main
@@ -55,7 +55,7 @@ func (fi gzipBindataFileInfo) Sys() interface{} {
return nil
}
var _gzipBindataAssetscssbootstrapmincss = []byte(
var _gzipBindataAssetsCssBootstrapmincss = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xbd\xef\x8f\xe3\x38\x92\x20\xfa\xb9\x1a\xe8\xff\x41\x5b\x8d\x41\x57" +
"\x4d\x59\x2e\xf9\x77\xda\x89\xce\xb7\xfb\xe6\x0e\xb7\x03\xdc\xec\x97\x9b\x0f\x07\xf4\xf4\x7b\xa0\x25\xda\xd6\x94" +
"\x2c\x69\x24\x39\x2b\xb3\xfb\xf6\xfe\xf6\x83\xf8\x4b\x41\x32\x48\xd1\x4e\x77\xcf\xdc\x62\xb7\xee\x7a\x9c\x62\x44" +
@@ -806,14 +806,14 @@ var _gzipBindataAssetscssbootstrapmincss = []byte(
"\x6f\x60\x83\x31\xfd\x46\x3e\xae\xb6\x0e\x28\xfe\xfd\xe4\x72\x0f\x83\x02\x88\x8b\x01\x82\xf5\x3c\x3e\x46\xfe\x4f" +
"\x00\x00\x00\xff\xff\x47\x37\xb0\x07\xc9\x28\x02\x00")
func gzipBindataAssetscssbootstrapmincss() (*gzipAsset, error) {
bytes := _gzipBindataAssetscssbootstrapmincss
func gzipBindataAssetsCssBootstrapmincss() (*gzipAsset, error) {
bytes := _gzipBindataAssetsCssBootstrapmincss
info := gzipBindataFileInfo{
name: "assets/css/bootstrap.min.css",
size: 141513,
md5checksum: "",
mode: os.FileMode(438),
modTime: time.Unix(1520997241, 0),
mode: os.FileMode(511),
modTime: time.Unix(1521004692, 0),
}
a := &gzipAsset{bytes: bytes, info: info}
@@ -821,7 +821,7 @@ func gzipBindataAssetscssbootstrapmincss() (*gzipAsset, error) {
return a, nil
}
var _gzipBindataAssetsfaviconico = []byte(
var _gzipBindataAssetsFaviconico = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x0b\x70\x55\xc7\x79\xde\x7b\xce\x45\x12\xb2\x90\xc4\xc3\xe6\x61" +
"\x3b\x90\xf8\x31\xc4\x19\x6c\x32\xe3\xc4\x34\xe3\xc6\x34\x6d\xed\xd4\x69\x62\x32\x49\x9a\xa6\x75\xea\x36\x33\xee" +
"\xd8\x9e\xb4\x75\xdc\x7a\xa6\xc5\x31\x02\xa6\xd3\x84\x47\x28\x6f\x3b\xc6\x3c\xcc\xeb\x9e\xbd\x08\x21\x04\x92\x28" +
@@ -967,14 +967,14 @@ var _gzipBindataAssetsfaviconico = []byte(
"\x0c\x24\x28\xcd\x41\x65\xd4\x2a\xc1\x2e\x17\x0e\x2a\x5b\xac\xb2\xc7\x2a\x4d\xab\x4c\xa1\xdf\xff\x0f\x00\x00\xff" +
"\xff\xc6\xb9\x24\x2f\xee\x3a\x00\x00")
func gzipBindataAssetsfaviconico() (*gzipAsset, error) {
bytes := _gzipBindataAssetsfaviconico
func gzipBindataAssetsFaviconico() (*gzipAsset, error) {
bytes := _gzipBindataAssetsFaviconico
info := gzipBindataFileInfo{
name: "assets/favicon.ico",
size: 15086,
md5checksum: "",
mode: os.FileMode(438),
modTime: time.Unix(1520997241, 0),
mode: os.FileMode(511),
modTime: time.Unix(1521004692, 0),
}
a := &gzipAsset{bytes: bytes, info: info}
@@ -982,7 +982,7 @@ func gzipBindataAssetsfaviconico() (*gzipAsset, error) {
return a, nil
}
var _gzipBindataAssetsjsjquery211js = []byte(
var _gzipBindataAssetsJsJquery211js = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xfd\x7b\x77\xdb\x46\x96\x28\x8a\xff\x2d\xaf\xe5\xef\x50\xa2\x73\x64" +
"\xd0\xe2\x43\xb2\x93\x74\x42\x99\xd6\xcf\xb1\x9d\x1e\x9d\x5f\xec\xb8\x23\x67\x32\xf7\x4a\xca\xa4\x48\x14\xc5\xb2" +
"\x41\x80\x41\x81\x92\xd8\xa1\xfa\xb3\xdf\xb5\x1f\xf5\x02\x40\xd9\xee\x4e\xcf\x39\x3d\x6b\x62\x11\x28\xd4\x63\xd7" +
@@ -3634,14 +3634,14 @@ var _gzipBindataAssetsjsjquery211js = []byte(
"\xfa\x6a\x18\xef\xb5\xaa\xc6\xb4\x04\x30\x01\x3d\xd6\x92\x74\x16\xc4\xcc\x86\x81\x87\x9d\x94\xce\x89\xbb\xe5\xdc" +
"\x66\xfb\xff\x03\x00\x00\xff\xff\x1d\x30\x27\xdd\x1d\xea\x03\x00")
func gzipBindataAssetsjsjquery211js() (*gzipAsset, error) {
bytes := _gzipBindataAssetsjsjquery211js
func gzipBindataAssetsJsJquery211js() (*gzipAsset, error) {
bytes := _gzipBindataAssetsJsJquery211js
info := gzipBindataFileInfo{
name: "assets/js/jquery-2.1.1.js",
size: 256541,
md5checksum: "",
mode: os.FileMode(438),
modTime: time.Unix(1520997241, 0),
mode: os.FileMode(511),
modTime: time.Unix(1521004692, 0),
}
a := &gzipAsset{bytes: bytes, info: info}
@@ -3706,9 +3706,9 @@ func GzipAssetNames() []string {
// _gzipbindata is a table, holding each asset generator, mapped to its name.
//
var _gzipbindata = map[string]func() (*gzipAsset, error){
"assets/css/bootstrap.min.css": gzipBindataAssetscssbootstrapmincss,
"assets/favicon.ico": gzipBindataAssetsfaviconico,
"assets/js/jquery-2.1.1.js": gzipBindataAssetsjsjquery211js,
"assets/css/bootstrap.min.css": gzipBindataAssetsCssBootstrapmincss,
"assets/favicon.ico": gzipBindataAssetsFaviconico,
"assets/js/jquery-2.1.1.js": gzipBindataAssetsJsJquery211js,
}
@@ -3764,11 +3764,11 @@ type gzipBintree struct {
var _gzipbintree = &gzipBintree{Func: nil, Children: map[string]*gzipBintree{
"assets": {Func: nil, Children: map[string]*gzipBintree{
"css": {Func: nil, Children: map[string]*gzipBintree{
"bootstrap.min.css": {Func: gzipBindataAssetscssbootstrapmincss, Children: map[string]*gzipBintree{}},
"bootstrap.min.css": {Func: gzipBindataAssetsCssBootstrapmincss, Children: map[string]*gzipBintree{}},
}},
"favicon.ico": {Func: gzipBindataAssetsfaviconico, Children: map[string]*gzipBintree{}},
"favicon.ico": {Func: gzipBindataAssetsFaviconico, Children: map[string]*gzipBintree{}},
"js": {Func: nil, Children: map[string]*gzipBintree{
"jquery-2.1.1.js": {Func: gzipBindataAssetsjsjquery211js, Children: map[string]*gzipBintree{}},
"jquery-2.1.1.js": {Func: gzipBindataAssetsJsJquery211js, Children: map[string]*gzipBintree{}},
}},
}},
}}

View File

@@ -55,7 +55,7 @@ func (r resource) loadFromBase(dir string) string {
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
// result = strings.Replace(result, "\n", "\r\n", -1)
}
return result
}
@@ -98,8 +98,11 @@ func TestEmbeddingGzipFilesIntoApp(t *testing.T) {
}
buf := new(bytes.Buffer)
reader.WriteTo(buf)
if rawContents != buf.String() {
t.Fatalf("[%d] of '%s': expected body:\n%s but got:\n%s", i, url, rawContents, buf.String())
if expected, got := rawContents, buf.String(); expected != got {
// t.Fatalf("[%d] of '%s': expected body:\n%s but got:\n%s", i, url, expected, got)
// let's reduce the output here...
// they are big files, no need to check for length here.
t.Fatalf("[%d] %s, expected body to look like: '%s...%s' but got '%s...%s'", i, url, expected[:40], expected[len(rawContents)-40:], got[:40], got[len(got)-40:])
}
}()
}

View File

@@ -47,7 +47,7 @@ func (r resource) loadFromBase(dir string) string {
}
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
// result = strings.Replace(result, "\n", "\r\n", -1)
}
return result
}

View File

@@ -6,11 +6,9 @@ package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/kataras/golog"
"github.com/kataras/iris"
// Note:
// For some reason the latest vscode-go language extension does not provide enough intelligence (parameters documentation and go to definition features)
@@ -80,10 +78,10 @@ func (b *Broker) listen() {
func (b *Broker) ServeHTTP(ctx context.Context) {
// Make sure that the writer supports flushing.
//
flusher, ok := ctx.ResponseWriter().(http.Flusher)
flusher, ok := ctx.ResponseWriter().Flusher()
if !ok {
ctx.StatusCode(iris.StatusInternalServerError)
ctx.StatusCode(iris.StatusHTTPVersionNotSupported)
ctx.WriteString("Streaming unsupported!")
return
}
@@ -102,19 +100,27 @@ func (b *Broker) ServeHTTP(ctx context.Context) {
// Signal the broker that we have a new connection.
b.newClients <- messageChan
// Remove this client from the map of connected clients
// when this handler exits.
defer func() {
b.closingClients <- messageChan
}()
// Listen to connection close or when the entire request handler chain exits and un-register messageChan.
// using the `ctx.ResponseWriter().CloseNotifier()` and `defer` for this single handler of the route:
/*
notifier, ok := ctx.ResponseWriter().CloseNotifier()
if ok {
go func() {
<-notifier.CloseNotify()
b.closingClients <- messageChan
}()
}
// Listen to connection close and un-register messageChan.
notify := ctx.ResponseWriter().(http.CloseNotifier).CloseNotify()
go func() {
<-notify
defer func() {
b.closingClients <- messageChan
}()
*/
// or by using the `ctx.OnClose`, which will take care all of the above for you:
ctx.OnClose(func() {
// Remove this client from the map of connected clients
// when this handler exits.
b.closingClients <- messageChan
}()
})
// block waiting for messages broadcast on this connection's messageChan.
for {
@@ -164,5 +170,5 @@ func main() {
// TIP: If you make use of it inside a web frontend application
// then checkout the "optional.sse.js.html" to use the javascript's API for SSE,
// it will also remove the browser's "loading" indicator while receiving those event messages.
app.Run(iris.Addr(":8080"))
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
}

View File

@@ -1,4 +1,5 @@
// +build go1.11beta2
package main
import (