1
0
mirror of https://github.com/kataras/iris.git synced 2026-03-14 04:09:37 +00:00

Add More Examples & Categorized in Folders & TOC

Former-commit-id: ce4d711a75a4ba08ffab075e6baa88724725885b
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-03-24 00:22:05 +02:00
parent 64ecc88195
commit 55c250c93a
97 changed files with 338 additions and 193 deletions

View File

@@ -1,43 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/cors"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
crs := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowCredentials: true,
})
app.Adapt(crs) // this line should be added
// adaptor supports cors allowed methods, middleware does not.
// if you want per-route-only cors
// then you should check https://github.com/iris-contrib/middleware/tree/master/cors
v1 := app.Party("/api/v1")
{
v1.Post("/home", func(c *iris.Context) {
app.Log(iris.DevMode, "lalala")
c.WriteString("Hello from /home")
})
v1.Get("/g", func(c *iris.Context) {
app.Log(iris.DevMode, "lalala")
c.WriteString("Hello from /home")
})
v1.Post("/h", func(c *iris.Context) {
app.Log(iris.DevMode, "lalala")
c.WriteString("Hello from /home")
})
}
app.Listen(":8080")
}

View File

@@ -1,69 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/gorillamux" // import the gorillamux adaptor
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // writes both prod and dev logs to the os.Stdout
app.Adapt(gorillamux.New()) // uses the gorillamux for routing and reverse routing
// set a custom 404 handler
app.OnError(iris.StatusNotFound, func(ctx *iris.Context) {
ctx.HTML(iris.StatusNotFound, "<h1> custom http error page </h1>")
})
app.Get("/healthcheck", h)
gamesMiddleware := func(ctx *iris.Context) {
println(ctx.Method() + ": " + ctx.Path())
ctx.Next()
}
games := app.Party("/games", gamesMiddleware)
{ // braces are optional of course, it's just a style of code
games.Get("/{gameID:[0-9]+}/clans", h)
games.Get("/{gameID:[0-9]+}/clans/clan/{publicID:[0-9]+}", h)
games.Get("/{gameID:[0-9]+}/clans/search", h)
games.Put("/{gameID:[0-9]+}/players/{publicID:[0-9]+}", h)
games.Put("/{gameID:[0-9]+}/clans/clan/{publicID:[0-9]+}", h)
games.Post("/{gameID:[0-9]+}/clans", h)
games.Post("/{gameID:[0-9]+}/players", h)
games.Post("/{gameID:[0-9]+}/clans/{publicID:[0-9]+}/leave", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/application", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/application/:action", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/invitation", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/invitation/:action", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/delete", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/promote", h)
games.Post("/{gameID:[0-9]+}/clans/{clanPublicID:[0-9]+}/memberships/demote", h)
}
myroute := app.Get("/anything/{anythingparameter:.*}", func(ctx *iris.Context) {
s := ctx.Param("anythingparameter")
ctx.Writef("The path after /anything is: %s", s)
}) // .ChangeName("myroute")
app.Get("/reverse_myroute", func(ctx *iris.Context) {
// reverse routing snippet using templates:
// https://github.com/kataras/iris/tree/v6/adaptors/view/_examples/template_html_3 (gorillamux)
// https://github.com/kataras/iris/tree/v6/adaptors/view/_examples/template_html_4 (httprouter)
myrouteRequestPath := app.Path(myroute.Name(), "anythingparameter", "something/here")
ctx.Writef("Should be '/anything/something/here': %s", myrouteRequestPath)
})
p := app.Party("mysubdomain.")
// http://mysubdomain.myhost.com/
p.Get("/", h)
app.Listen(":8080")
}
func h(ctx *iris.Context) {
ctx.HTML(iris.StatusOK, "<h1>Path<h1/>"+ctx.Path())
}

View File

@@ -1,39 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
)
func hello(ctx *iris.Context) {
ctx.Writef("Hello from %s", ctx.Path())
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
app.OnError(iris.StatusNotFound, func(ctx *iris.Context) {
ctx.HTML(iris.StatusNotFound, "<h1>Custom not found handler </h1>")
})
app.Get("/", hello)
app.Get("/users/:userid", func(ctx *iris.Context) {
ctx.Writef("Hello user with id: %s", ctx.Param("userid"))
})
app.Get("/myfiles/*file", func(ctx *iris.Context) {
ctx.HTML(iris.StatusOK, "Hello, the dynamic path after /myfiles is:<br/> <b>"+ctx.Param("file")+"</b>")
})
app.Get("/users/:userid/messages/:messageid", func(ctx *iris.Context) {
ctx.HTML(iris.StatusOK, `Message from user with id:<br/> <b>`+ctx.Param("userid")+`</b>,
message id: <b>`+ctx.Param("messageid")+`</b>`)
})
// http://127.0.0.1:8080/users/42
// http://127.0.0.1:8080/myfiles/mydirectory/myfile.zip
// http://127.0.0.1:8080/users/42/messages/1
app.Listen(":8080")
}

View File

@@ -1,73 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/sessions"
"gopkg.in/kataras/iris.v6/adaptors/sessions/sessiondb/redis"
"gopkg.in/kataras/iris.v6/adaptors/sessions/sessiondb/redis/service"
)
func main() {
// replace with your running redis' server settings:
db := redis.New(service.Config{Network: service.DefaultRedisNetwork,
Addr: service.DefaultRedisAddr,
Password: "",
Database: "",
MaxIdle: 0,
MaxActive: 0,
IdleTimeout: service.DefaultRedisIdleTimeout,
Prefix: "",
MaxAgeSeconds: service.DefaultRedisMaxAgeSeconds}) // optionally configure the bridge between your redis server
mySessions := sessions.New(sessions.Config{Cookie: "mysessionid"})
//
// IMPORTANT:
//
mySessions.UseDatabase(db)
// the rest of the code stays the same.
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
// Adapt the session manager we just created
app.Adapt(mySessions)
app.Get("/", func(ctx *iris.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx *iris.Context) {
//set session values
ctx.Session().Set("name", "iris")
//test if setted here
ctx.Writef("All ok session setted to: %s", ctx.Session().GetString("name"))
})
app.Get("/get", func(ctx *iris.Context) {
// get a specific key, as string, if no found returns just an empty string
name := ctx.Session().GetString("name")
ctx.Writef("The name on the /set was: %s", name)
})
app.Get("/delete", func(ctx *iris.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx *iris.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx *iris.Context) {
//destroy, removes the entire session data and cookie
ctx.SessionDestroy()
})
app.Listen(":8080")
}

View File

@@ -1,79 +0,0 @@
package main
import (
// developers can use any library to add a custom cookie encoder/decoder.
// At this example we use the gorilla's securecookie library:
"github.com/gorilla/securecookie"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/sessions"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
cookieName := "mycustomsessionid"
// AES only supports key sizes of 16, 24 or 32 bytes.
// You either need to provide exactly that amount or you derive the key from what you type in.
hashKey := []byte("the-big-and-secret-fash-key-here")
blockKey := []byte("lot-secret-of-characters-big-too")
secureCookie := securecookie.New(hashKey, blockKey)
mySessions := sessions.New(sessions.Config{
Cookie: cookieName,
Encode: secureCookie.Encode,
Decode: secureCookie.Decode,
})
app.Adapt(mySessions)
// OPTIONALLY:
// import "gopkg.in/kataras/iris.v6/adaptors/sessions/sessiondb/redis"
// or import "github.com/kataras/go-sessions/sessiondb/$any_available_community_database"
// mySessions.UseDatabase(redis.New(...))
app.Adapt(mySessions) // Adapt the session manager we just created.
app.Get("/", func(ctx *iris.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx *iris.Context) {
//set session values
ctx.Session().Set("name", "iris")
//test if setted here
ctx.Writef("All ok session setted to: %s", ctx.Session().GetString("name"))
})
app.Get("/get", func(ctx *iris.Context) {
// get a specific key, as string, if no found returns just an empty string
name := ctx.Session().GetString("name")
ctx.Writef("The name on the /set was: %s", name)
})
app.Get("/delete", func(ctx *iris.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx *iris.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx *iris.Context) {
//destroy, removes the entire session data and cookie
ctx.SessionDestroy()
}) // Note about destroy:
//
// You can destroy a session outside of a handler too, using the:
// mySessions.DestroyByID
// mySessions.DestroyAll
app.Listen(":8080")
}

View File

@@ -1,82 +0,0 @@
package main
import (
"time"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/sessions"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
mySessions := sessions.New(sessions.Config{
// Cookie string, the session's client cookie name, for example: "mysessionid"
//
// Defaults to "irissessionid"
Cookie: "mysessionid",
// it's time.Duration, from the time cookie is created, how long it can be alive?
// 0 means no expire.
// -1 means expire when browser closes
// or set a value, like 2 hours:
Expires: time.Hour * 2,
// the length of the sessionid's cookie's value
CookieLength: 32,
// if you want to invalid cookies on different subdomains
// of the same host, then enable it
DisableSubdomainPersistence: false,
// want to be crazy safe? Take a look at the "securecookie" example folder.
})
// OPTIONALLY:
// import "gopkg.in/kataras/iris.v6/adaptors/sessions/sessiondb/redis"
// or import "github.com/kataras/go-sessions/sessiondb/$any_available_community_database"
// mySessions.UseDatabase(redis.New(...))
app.Adapt(mySessions) // Adapt the session manager we just created.
app.Get("/", func(ctx *iris.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx *iris.Context) {
//set session values
ctx.Session().Set("name", "iris")
//test if setted here
ctx.Writef("All ok session setted to: %s", ctx.Session().GetString("name"))
})
app.Get("/get", func(ctx *iris.Context) {
// get a specific key, as string, if no found returns just an empty string
name := ctx.Session().GetString("name")
ctx.Writef("The name on the /set was: %s", name)
})
app.Get("/delete", func(ctx *iris.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx *iris.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx *iris.Context) {
//destroy, removes the entire session data and cookie
ctx.SessionDestroy()
})
// Note about Destroy:
//
// You can destroy a session outside of a handler too, using the:
// mySessions.DestroyByID
// mySessions.DestroyAll
app.Listen(":8080")
}

View File

@@ -1,36 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/typescript"
)
// NOTE: Some machines don't allow to install typescript automatically, so if you don't have typescript installed
// and the typescript adaptor doesn't works for you then follow the below steps:
// 1. close the iris server
// 2. open your terminal and execute: npm install -g typescript
// 3. start your iris server, it should be work, as expected, now.
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New()) // adapt a router, order doesn't matters but before Listen.
ts := typescript.New()
ts.Config.Dir = "./www/scripts"
app.Adapt(ts) // adapt the typescript compiler adaptor
app.StaticWeb("/", "./www") // serve the index.html
app.Listen(":8080")
}
// open http://localhost:8080
// go to ./www/scripts/app.ts
// make a change
// reload the http://localhost:8080 and you should see the changes
//
// what it does?
// - compiles the typescript files using default compiler options if not tsconfig found
// - watches for changes on typescript files, if a change then it recompiles the .ts to .js
//
// same as you used to do with gulp-like tools, but here at Iris I do my bests to help GO developers.

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Load my script (lawl)</title>
</head>
<body>
<script src="scripts/app.js"></script>
</body>
</html>

View File

@@ -1,16 +0,0 @@
class User{
private name: string;
constructor(fullname:string) {
this.name = fullname;
}
Hi(msg: string): string {
return msg + " "+ this.name;
}
}
var user = new User("kataras");
var hi = user.Hi("Hello");
window.alert(hi);

View File

@@ -1,35 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/typescript" // optinally
"gopkg.in/kataras/iris.v6/adaptors/typescript/editor"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New()) // adapt a router, order doesn't matters
// optionally but good to have, I didn't put inside editor or the editor in the typescript compiler adaptors
// because you may use tools like gulp and you may use the editor without the typescript compiler adaptor.
// but if you need auto-compilation on .ts, we have a solution:
ts := typescript.New()
ts.Config.Dir = "./www/scripts/"
app.Adapt(ts) // adapt the typescript compiler adaptor
editorConfig := editor.Config{
Hostname: "127.0.0.1",
Port: 4444,
WorkingDir: "./www/scripts/", // "/path/to/the/client/side/directory/",
Username: "myusername",
Password: "mypassword",
}
e := editor.New(editorConfig)
app.Adapt(e) // adapt the editor
app.StaticWeb("/", "./www") // serve the index.html
app.Listen(":8080")
}

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Load my script (lawl)</title>
</head>
<body>
<script src="scripts/app.js"></script>
</body>
</html>

View File

@@ -1,16 +0,0 @@
class User{
private name: string;
constructor(fullname:string) {
this.name = fullname;
}
Hi(msg: string): string {
return msg + " " + this.name;
}
}
var user = new User("kataras");
var hi = user.Hi("Hello");
window.alert(hi);

View File

@@ -1,22 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": false,
"target": "ES5",
"noEmit": false,
"watch":true,
"noEmitOnError": true,
"experimentalDecorators": false,
"outDir": "./",
"charset": "UTF-8",
"noLib": false,
"diagnostics": true,
"declaration": false
},
"files": [
"./app.ts"
]
}

View File

@@ -1,48 +0,0 @@
package main
import (
"io"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
)
func main() {
app := iris.New()
// output startup banner and error logs on os.Stdout
app.Adapt(iris.DevLogger())
// set the router, you can choose gorillamux too
app.Adapt(httprouter.New())
// Custom Render Policy to override or create new content-type render
// i,e: "text/html" with a prefix,
// we will just write to the writer and return false
// to continue to the next contentType-matched renderer if any.
app.Adapt(iris.RenderPolicy(func(out io.Writer, contentType string, binding interface{}, options ...map[string]interface{}) (bool, error) {
if contentType == "text/html" {
if content, ok := binding.(string); ok {
out.Write([]byte("<pre>My Custom prefix</pre><br/>" + content))
}
}
// continue to the next, no error
// note: if we wanted to stop here we would return true instead of false.
return false, nil
}))
app.Get("", func(ctx *iris.Context) {
// These content-types are not managed by our RenderPolicy:
// text, binary and html content-types are
// not rendered via serializers, you have to
// use the ctx.Render functions instead.
// so something like this:
// ctx.Text(iris.StatusOK, "my text content body here!")
// will NOT work with out custom render policy.
ctx.Render("text/html",
"my text content body here!")
})
app.Listen(":8080")
}

View File

@@ -1,59 +0,0 @@
package main
import (
"encoding/xml"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
// ExampleXML just a test struct to view represents xml content-type
type ExampleXML struct {
XMLName xml.Name `xml:"example"`
One string `xml:"one,attr"`
Two string `xml:"two,attr"`
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(gorillamux.New())
app.Get("/data", func(ctx *iris.Context) {
ctx.Data(iris.StatusOK, []byte("Some binary data here."))
})
app.Get("/text", func(ctx *iris.Context) {
ctx.Text(iris.StatusOK, "Plain text here")
})
app.Get("/json", func(ctx *iris.Context) {
ctx.JSON(iris.StatusOK, map[string]string{"hello": "json"}) // or myjsonStruct{hello:"json}
})
app.Get("/jsonp", func(ctx *iris.Context) {
ctx.JSONP(iris.StatusOK, "callbackName", map[string]string{"hello": "jsonp"})
})
app.Get("/xml", func(ctx *iris.Context) {
ctx.XML(iris.StatusOK, ExampleXML{One: "hello", Two: "xml"}) // or iris.Map{"One":"hello"...}
})
app.Get("/markdown", func(ctx *iris.Context) {
ctx.Markdown(iris.StatusOK, "# Hello Dynamic Markdown Iris")
})
app.Adapt(view.HTML("./templates", ".html"))
app.Get("/template", func(ctx *iris.Context) {
ctx.MustRender(
"hi.html", // the file name of the template relative to the './templates'
iris.Map{"Name": "Iris"}, // the .Name inside the ./templates/hi.html
iris.Map{"gzip": false}, // enable gzip for big files
)
})
app.Listen(":8080")
}

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Hi Iris</title>
</head>
<body>
<h1>Hi {{.Name}} </h1>
</body>
</html>

View File

@@ -1,238 +0,0 @@
// Code generated by go-bindata.
// sources:
// templates/hi.html
// DO NOT EDIT!
// NOTE: execute your own look main.go
package main
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
)
func bindataRead(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
clErr := gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
if clErr != nil {
return nil, err
}
return buf.Bytes(), nil
}
type asset struct {
bytes []byte
info os.FileInfo
}
type bindataFileInfo struct {
name string
size int64
mode os.FileMode
modTime time.Time
}
func (fi bindataFileInfo) Name() string {
return fi.name
}
func (fi bindataFileInfo) Size() int64 {
return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
return false
}
func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var _templatesHiHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb2\xc9\x28\xc9\xcd\xb1\xe3\xe5\xb2\xc9\x48\x4d\x4c\x01\xd1\x25\x99\x25\x39\xa9\x76\x1e\x99\x0a\x9e\x45\x99\xc5\x0a\xd1\x21\x1e\xae\x0a\x21\x9e\x21\x3e\xae\xb1\x36\xfa\x10\x29\xa0\x1a\x7d\x98\xe2\xa4\xfc\x94\x4a\x20\xcd\x69\x93\x61\x08\xd2\x52\x5d\xad\xe7\x97\x98\x9b\x5a\x5b\x0b\x52\x03\x95\x03\x2a\x86\xd8\x00\x08\x00\x00\xff\xff\xed\x0e\xad\x42\x6a\x00\x00\x00")
func templatesHiHtmlBytes() ([]byte, error) {
return bindataRead(
_templatesHiHtml,
"templates/hi.html",
)
}
func templatesHiHtml() (*asset, error) {
bytes, err := templatesHiHtmlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "templates/hi.html", size: 106, mode: os.FileMode(438), modTime: time.Unix(1487682349, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
}
return a.bytes, nil
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
a, err := Asset(name)
if err != nil {
panic("asset: Asset(" + name + "): " + err.Error())
}
return a
}
// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
}
return a.info, nil
}
return nil, fmt.Errorf("AssetInfo %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"templates/hi.html": templatesHiHtml,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for childName := range node.Children {
rv = append(rv, childName)
}
return rv, nil
}
type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
"templates": &bintree{nil, map[string]*bintree{
"hi.html": &bintree{templatesHiHtml, map[string]*bintree{}},
}},
}}
// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
data, err := Asset(name)
if err != nil {
return err
}
info, err := AssetInfo(name)
if err != nil {
return err
}
err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
if err != nil {
return err
}
err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
if err != nil {
return err
}
err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
if err != nil {
return err
}
return nil
}
// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
children, err := AssetDir(name)
// File
if err != nil {
return RestoreAsset(dir, name)
}
// Dir
for _, child := range children {
err = RestoreAssets(dir, filepath.Join(name, child))
if err != nil {
return err
}
}
return nil
}
func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

View File

@@ -1,25 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
// $ go-bindata ./templates/...
// $ go build
// $ ./template_binary
// templates are not used, you can delete the folder and run the example
app.Adapt(view.HTML("./templates", ".html").Binary(Asset, AssetNames))
app.Get("/hi", hi)
app.Listen(":8080")
}
func hi(ctx *iris.Context) {
ctx.MustRender("hi.html", struct{ Name string }{Name: "iris"})
}

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Hi Iris [THE TITLE]</title>
</head>
<body>
<h1>Hi {{.Name}}
</body>
</html>

View File

@@ -1,23 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
func main() {
app := iris.New(iris.Configuration{Gzip: false, Charset: "UTF-8"}) // defaults to these
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
app.Adapt(view.HTML("./templates", ".html"))
app.Get("/hi", hi)
app.Listen(":8080")
}
func hi(ctx *iris.Context) {
ctx.MustRender("hi.html", struct{ Name string }{Name: "iris"})
}

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Hi Iris</title>
</head>
<body>
<h1>Hi {{.Name}} </h1>
</body>
</html>

View File

@@ -1,32 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
type mypage struct {
Title string
Message string
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
tmpl := view.HTML("./templates", ".html")
tmpl.Layout("layout.html")
app.Adapt(tmpl)
app.Get("/", func(ctx *iris.Context) {
ctx.Render("mypage.html", mypage{"My Page title", "Hello world!"}, iris.Map{"gzip": true})
// Note that: you can pass "layout" : "otherLayout.html" to bypass the config's Layout property
// or iris.NoLayout to disable layout on this render action.
// third is an optional parameter
})
app.Listen(":8080")
}

View File

@@ -1,11 +0,0 @@
<html>
<head>
<title>My Layout</title>
</head>
<body>
<h1>Body is:</h1>
<!-- Render the current template here -->
{{ yield }}
</body>
</html>

View File

@@ -1,4 +0,0 @@
<h1>
Title: {{.Title}}
</h1>
<h3>Message: {{.Message}} </h3>

View File

@@ -1,3 +0,0 @@
## Info
This folder examines the {{render "dir/templatefilename"}} functionality to manually render any template inside any template

View File

@@ -1,49 +0,0 @@
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(httprouter.New())
tmpl := view.HTML("./templates", ".html")
tmpl.Layout("layouts/layout.html")
tmpl.Funcs(map[string]interface{}{
"greet": func(s string) string {
return "Greetings " + s + "!"
},
})
app.Adapt(tmpl)
app.Get("/", func(ctx *iris.Context) {
if err := ctx.Render("page1.html", nil); err != nil {
println(err.Error())
}
})
// remove the layout for a specific route
app.Get("/nolayout", func(ctx *iris.Context) {
if err := ctx.Render("page1.html", nil, iris.RenderOptions{"layout": iris.NoLayout}); err != nil {
println(err.Error())
}
})
// set a layout for a party, .Layout should be BEFORE any Get or other Handle party's method
my := app.Party("/my").Layout("layouts/mylayout.html")
{
my.Get("/", func(ctx *iris.Context) {
ctx.MustRender("page1.html", nil)
})
my.Get("/other", func(ctx *iris.Context) {
ctx.MustRender("page1.html", nil)
})
}
app.Listen(":8080")
}

View File

@@ -1,12 +0,0 @@
<html>
<head>
<title>Layout</title>
</head>
<body>
<h1>This is the global layout</h1>
<br />
<!-- Render the current template here -->
{{ yield }}
</body>
</html>

View File

@@ -1,12 +0,0 @@
<html>
<head>
<title>my Layout</title>
</head>
<body>
<h1>This is the layout for the /my/ and /my/other routes only</h1>
<br />
<!-- Render the current template here -->
{{ yield }}
</body>
</html>

View File

@@ -1,7 +0,0 @@
<div style="background-color: black; color: blue">
<h1>Page 1 {{ greet "iris developer"}}</h1>
{{ render "partials/page1_partial1.html"}}
</div>

View File

@@ -1,3 +0,0 @@
<div style="background-color: white; color: red">
<h1>Page 1's Partial 1</h1>
</div>

View File

@@ -1,103 +0,0 @@
// Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines.
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(view.HTML("./templates", ".html").Reload(true))
startWithHTTPRouter(app)
// or uncomment
// startWithGorillamux()
app.Listen("localhost:8080")
}
func writePathHandler(ctx *iris.Context) {
ctx.Writef("Hello from %s.", ctx.Path())
}
func startWithHTTPRouter(app *iris.Framework) {
app.Adapt(httprouter.New())
app.Get("/mypath", writePathHandler).ChangeName("my-page1")
app.Get("/mypath2/:param1/:param2", writePathHandler).ChangeName("my-page2")
app.Get("/mypath3/:param1/statichere/:param2", writePathHandler).ChangeName("my-page3")
app.Get("/mypath4/:param1/statichere/:param2/:otherparam/*something", writePathHandler).ChangeName("my-page4")
// same with Handle/Func
app.HandleFunc("GET", "/mypath5/:param1/statichere/:param2/:otherparam/anything/*something", writePathHandler).ChangeName("my-page5")
app.Get("/mypath6/:param1/:param2/staticParam/:param3AfterStatic", writePathHandler).ChangeName("my-page6")
app.Get("/", func(ctx *iris.Context) {
// for /mypath6...
paramsAsArray := []string{"param1", "theParam1",
"param2", "theParam2",
"param3AfterStatic", "theParam3"}
if err := ctx.Render("page.html", iris.Map{"ParamsAsArray": paramsAsArray}); err != nil {
panic(err)
}
})
app.Get("/redirect/:namedRoute", func(ctx *iris.Context) {
routeName := ctx.Param("namedRoute")
println("The full uri of " + routeName + "is: " + app.URL(routeName))
// if routeName == "my-page1"
// prints: The full uri of my-page1 is: http://127.0.0.1:8080/mypath
ctx.RedirectTo(routeName)
// http://127.0.0.1:8080/redirect/my-page1 will redirect to -> http://127.0.0.1:8080/mypath
})
}
// for gorillamux adaptor is the same thing, the path syntax is the only thing changed ofc.
// Note: Here, we could use app.RouteParam("param1") without even care what router is being used,
// but I have two examples of the same thing in order to be more understable for you.
func startWithGorillamux(app *iris.Framework) {
app.Adapt(gorillamux.New())
app.Get("/mypath", writePathHandler).ChangeName("my-page1")
app.Get("/mypath2/{param1}/{param2}", writePathHandler).ChangeName("my-page2")
app.Get("/mypath3/{param1}/statichere/{param2}", writePathHandler).ChangeName("my-page3")
app.Get("/mypath4/{param1}/statichere/{param2}/{otherparam}/{something:.*}", writePathHandler).ChangeName("my-page4")
// same with Handle/Func
app.HandleFunc("GET", "/mypath5/{param1}/statichere/{param2}/{otherparam}/anything/{something:.*}", writePathHandler).ChangeName("my-page5")
app.Get("/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}", writePathHandler).ChangeName("my-page6")
app.Get("/", func(ctx *iris.Context) {
// for /mypath6...
paramsAsArray := []string{"param1", "theParam1",
"param2", "theParam2",
"param3AfterStatic", "theParam3"}
if err := ctx.Render("page.html", iris.Map{"ParamsAsArray": paramsAsArray}); err != nil {
panic(err)
}
})
app.Get("/redirect/{namedRoute}", func(ctx *iris.Context) {
routeName := ctx.Param("namedRoute")
println("The full uri of " + routeName + "is: " + app.URL(routeName))
// if routeName == "my-page1"
// prints: The full uri of my-page1 is: http://127.0.0.1:8080/mypath
ctx.RedirectTo(routeName)
// http://127.0.0.1:8080/redirect/my-page1 will redirect to -> http://127.0.0.1:8080/mypath
})
app.Listen("localhost:8080")
}

View File

@@ -1,29 +0,0 @@
<a href="{{url "my-page1"}}">http://127.0.0.1:8080/mypath</a>
<br />
<br />
<a href="{{url "my-page2" "param1" "theParam1" "param2" "theParam2"}}">http://localhost:8080/mypath2/:param1/:param2</a>
or path only:
<a href="{{urlpath "my-page2" "param1" "theParam1" "param2" "theParam2"}}">/mypath2/:param1/:param2</a>
<br />
<br />
<a href="{{url "my-page3" "param1" "theParam1" "param2" "theParam2AfterStatic"}}">
http://localhost:8080/mypath3/:param1/statichere/:param2</a>
<br />
<br />
<a href="{{url "my-page4" "param1" "theParam1" "param2" "theparam2AfterStatic" "otherparam" "otherParam" "something" "matchAnything"}}">http://localhost/mypath4/:param1/statichere/:param2/:otherparam/*something</a>
<br />
<br />
<a href="{{url "my-page5" "param1" "theParam1" "param2" "theParam2AfterStatic" "otherparam" "otherParam" "something" "matchAnythingAfterStatic"}}">
http://localhost:8080/mypath5/:param1/statichere/:param2/:otherparam/anything/*anything</a>
<br />
<br />
<a href={{url "my-page6" .ParamsAsArray }}>http://localhost:8080/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}</a>

View File

@@ -1,32 +0,0 @@
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
::1 localhost
#-IRIS-For development machine, you have to configure your dns also for online, search google how to do it if you don't know
127.0.0.1 username1.127.0.0.1
127.0.0.1 username2.127.0.0.1
127.0.0.1 username3.127.0.0.1
127.0.0.1 username4.127.0.0.1
127.0.0.1 username5.127.0.0.1
# note that you can always use custom subdomains
#-END IRIS-
# Windows: Drive:/Windows/system32/drivers/etc/hosts, on Linux: /etc/hosts

View File

@@ -1,53 +0,0 @@
// Package main an example on how to naming your routes & use the custom 'url' HTML Template Engine, same for other template engines.
package main
import (
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/gorillamux"
"gopkg.in/kataras/iris.v6/adaptors/view"
)
func main() {
app := iris.New()
app.Adapt(iris.DevLogger())
app.Adapt(gorillamux.New())
app.Adapt(view.HTML("./templates", ".html"))
app.Get("/mypath", emptyHandler).ChangeName("my-page1")
app.Get("/mypath2/{param1}/{param2}", emptyHandler).ChangeName("my-page2")
app.Get("/mypath3/{param1}/statichere/{param2}", emptyHandler).ChangeName("my-page3")
app.Get("/mypath4/{param1}/statichere/{param2}/{otherparam}/{something:.*}", emptyHandler).ChangeName("my-page4")
// same with Handle/Func
app.HandleFunc("GET", "/mypath5/{param1}/statichere/{param2}/{otherparam}/anything/{something:.*}", emptyHandler).ChangeName("my-page5")
app.Get("/mypath6/{param1}/{param2}/staticParam/{param3AfterStatic}", emptyHandler).ChangeName("my-page6")
app.Get("/", func(ctx *iris.Context) {
// for /mypath6...
paramsAsArray := []string{"param1", "theParam1",
"param2", "theParam2",
"param3AfterStatic", "theParam3"}
if err := ctx.Render("page.html", iris.Map{"ParamsAsArray": paramsAsArray}); err != nil {
panic(err)
}
})
app.Get("/redirect/{namedRoute}", func(ctx *iris.Context) {
routeName := ctx.Param("namedRoute")
println("The full uri of " + routeName + "is: " + app.URL(routeName))
// if routeName == "my-page1"
// prints: The full uri of my-page1 is: http://127.0.0.1:8080/mypath
ctx.RedirectTo(routeName)
// http://127.0.0.1:8080/redirect/my-page1 will redirect to -> http://127.0.0.1:8080/mypath
})
app.Listen("localhost:8080")
}
func emptyHandler(ctx *iris.Context) {
ctx.Writef("Hello from %s.", ctx.Path())
}

View File

@@ -1,16 +0,0 @@
<!-- the only difference between normal named routes and dynamic subdomains named routes is that the first argument of url
is the subdomain part instead of named parameter-->
<a href="{{url "dynamic-subdomain1" "username1"}}">username1.127.0.0.1:8080/mypath</a>
<br />
<br />
<a href="{{url "dynamic-subdomain2" "username2" "theParam1" "theParam2"}}">username2.127.0.0.1:8080/mypath2/{param1}/{param2}</a>
<br />
<br />
<a href="{{url "dynamic-subdomain3" "username3" "theParam1" "theParam2AfterStatic"}}">username3.127.0.0.1:8080/mypath3/{param1}/statichere/{param2}</a>
<br />
<br />
<a href="{{url "dynamic-subdomain4" "username4" "theParam1" "theparam2AfterStatic" "otherParam" "matchAnything"}}">username4.127.0.0.1:8080/mypath4/{param1}/statichere/{param2}/{otherParam}/{something:.*}</a>
<br />
<br />
<a href="{{url "dynamic-subdomain5" .ParamsAsArray }}" >username5.127.0.0.1:8080/mypath6/{param1}/{param2}/staticParam/{param3}AfterStatic</a>

View File

@@ -1,99 +0,0 @@
package main
import (
"fmt" // optional
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
"gopkg.in/kataras/iris.v6/adaptors/websocket"
)
type clientPage struct {
Title string
Host string
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
ws := websocket.New(websocket.Config{
// the path which the websocket client should listen/registered to,
Endpoint: "/my_endpoint",
// the client-side javascript static file path
// which will be served by Iris.
// default is /iris-ws.js
// if you change that you have to change the bottom of templates/client.html
// script tag:
ClientSourcePath: "/iris-ws.js",
//
// Set the timeouts, 0 means no timeout
// websocket has more configuration, go to ../../config.go for more:
// WriteTimeout: 0,
// ReadTimeout: 0,
// by-default all origins are accepted, you can change this behavior by setting:
// CheckOrigin: (r *http.Request ) bool {},
//
//
// 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 *iris.Context) string {},
})
app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
app.StaticWeb("/js", "./static/js") // serve our custom javascript code
app.Get("/", func(ctx *iris.Context) {
ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
})
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())
})
})
app.Listen(":8080")
}

View File

@@ -1,38 +0,0 @@
var messageTxt;
var messages;
$(function () {
messageTxt = $("#messageTxt");
messages = $("#messages");
w = new Ws("ws://" + 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;
}
}

View File

@@ -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" type="text/javascript"></script>
<!-- This is auto-serving by the Iris, you don't need to have this file in your disk-->
<script src="/iris-ws.js" type="text/javascript"></script>
<!-- -->
<script src="js/chat.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -1,113 +0,0 @@
package main
import (
"fmt"
"sync"
"time"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
"gopkg.in/kataras/iris.v6/adaptors/websocket"
)
type clientPage struct {
Title string
Host string
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
ws := websocket.New(websocket.Config{
// the path which the websocket client should listen/registered to,
Endpoint: "/my_endpoint",
// the client-side javascript static file path
// which will be served by Iris.
// default is /iris-ws.js
// if you change that you have to change the bottom of templates/client.html
// script tag:
ClientSourcePath: "/iris-ws.js",
//
// Set the timeouts, 0 means no timeout
// websocket has more configuration, go to ../../config.go for more:
// WriteTimeout: 0,
// ReadTimeout: 0,
// by-default all origins are accepted, you can change this behavior by setting:
// CheckOrigin: (r *http.Request ) bool {},
//
//
// 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 *iris.Context) string {},
})
app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
app.StaticWeb("/js", "./static/js") // serve our custom javascript code
app.Get("/", func(ctx *iris.Context) {
ctx.Render("client.html", clientPage{"Client Page", ctx.ServerHost()})
})
Conn := make(map[websocket.Connection]bool)
var myChatRoom = "room1"
var mutex = new(sync.Mutex)
ws.OnConnection(func(c websocket.Connection) {
c.Join(myChatRoom)
mutex.Lock()
Conn[c] = true
mutex.Unlock()
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
}
})
c.OnDisconnect(func() {
mutex.Lock()
delete(Conn, c)
mutex.Unlock()
fmt.Printf("\nConnection with ID: %s has been disconnected!\n", c.ID())
})
})
var delay = 1 * time.Second
go func() {
i := 0
for {
mutex.Lock()
broadcast(Conn, fmt.Sprintf("aaaa %d\n", i))
mutex.Unlock()
time.Sleep(delay)
i++
}
}()
go func() {
i := 0
for {
mutex.Lock()
broadcast(Conn, fmt.Sprintf("aaaa2 %d\n", i))
mutex.Unlock()
time.Sleep(delay)
i++
}
}()
app.Listen(":8080")
}
func broadcast(Conn map[websocket.Connection]bool, message string) {
for k := range Conn {
k.To("room1").Emit("chat", message)
}
}

View File

@@ -1,38 +0,0 @@
var messageTxt;
var messages;
$(function () {
messageTxt = $("#messageTxt");
messages = $("#messages");
w = new Ws("ws://" + 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;
}
}

View File

@@ -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" type="text/javascript"></script>
<!-- This is auto-serving by the Iris, you don't need to have this file in your disk-->
<script src="/iris-ws.js" type="text/javascript"></script>
<!-- -->
<script src="js/chat.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -1,179 +0,0 @@
package main
// Run first `go run main.go server`
// and `go run main.go client` as many times as you want.
// Originally written by: github.com/antlaw to describe an old kataras/go-websocket's issue
// which you can find here: https://github.com/kataras/go-websocket/issues/24
import (
"fmt"
"os"
"strings"
"time"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/websocket"
xwebsocket "golang.org/x/net/websocket"
)
// WS is the current websocket connection
var WS *xwebsocket.Conn
func main() {
if len(os.Args) == 2 && strings.ToLower(os.Args[1]) == "server" {
ServerLoop()
} else if len(os.Args) == 2 && strings.ToLower(os.Args[1]) == "client" {
ClientLoop()
} else {
fmt.Println("wsserver [server|client]")
}
}
/////////////////////////////////////////////////////////////////////////
// client side
func sendUntilErr(sendInterval int) {
i := 1
for {
time.Sleep(time.Duration(sendInterval) * time.Second)
err := SendMessage("2", "all", "objectupdate", "2.UsrSchedule_v1_1")
if err != nil {
fmt.Println("failed to send join message", err.Error())
return
}
fmt.Println("objectupdate", i)
i++
}
}
func recvUntilErr() {
var msg = make([]byte, 2048)
var n int
var err error
i := 1
for {
if n, err = WS.Read(msg); err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("%v Received: %s.%v\n", time.Now(), string(msg[:n]), i)
i++
}
}
//ConnectWebSocket connect a websocket to host
func ConnectWebSocket() error {
var origin = "http://localhost/"
var url = "ws://localhost:9090/socket"
var err error
WS, err = xwebsocket.Dial(url, "", origin)
return err
}
// CloseWebSocket closes the current websocket connection
func CloseWebSocket() error {
if WS != nil {
return WS.Close()
}
return nil
}
// SendMessage broadcast a message to server
func SendMessage(serverID, to, method, message string) error {
buffer := []byte(message)
return SendtBytes(serverID, to, method, buffer)
}
// SendtBytes broadcast a message to server
func SendtBytes(serverID, to, method string, message []byte) error {
// look https://github.com/kataras/iris/tree/master/adaptors/websocket/message.go , client.go and client.js
// to understand the buffer line:
buffer := []byte(fmt.Sprintf("iris-websocket-message:%v;0;%v;%v;", method, serverID, to))
buffer = append(buffer, message...)
_, err := WS.Write(buffer)
if err != nil {
fmt.Println(err)
return err
}
return nil
}
// ClientLoop connects to websocket server, the keep send and recv dataS
func ClientLoop() {
for {
time.Sleep(time.Second)
err := ConnectWebSocket()
if err != nil {
fmt.Println("failed to connect websocket", err.Error())
continue
}
// time.Sleep(time.Second)
err = SendMessage("2", "all", "join", "dummy2")
go sendUntilErr(1)
recvUntilErr()
err = CloseWebSocket()
if err != nil {
fmt.Println("failed to close websocket", err.Error())
}
}
}
/////////////////////////////////////////////////////////////////////////
// server side
// OnConnect handles incoming websocket connection
func OnConnect(c websocket.Connection) {
fmt.Println("socket.OnConnect()")
c.On("join", func(message string) { OnJoin(message, c) })
c.On("objectupdate", func(message string) { OnObjectUpdated(message, c) })
// ok works too c.EmitMessage([]byte("dsadsa"))
c.OnDisconnect(func() { OnDisconnect(c) })
}
// ServerLoop listen and serve websocket requests
func ServerLoop() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
ws := websocket.New(websocket.Config{Endpoint: "/socket"})
app.Adapt(ws)
ws.OnConnection(OnConnect)
app.Listen("0.0.0.0:9090")
}
// OnJoin handles Join broadcast group request
func OnJoin(message string, c websocket.Connection) {
t := time.Now()
c.Join("server2")
fmt.Println("OnJoin() time taken:", time.Since(t))
}
// OnObjectUpdated broadcasts to all client an incoming message
func OnObjectUpdated(message string, c websocket.Connection) {
t := time.Now()
s := strings.Split(message, ";")
if len(s) != 3 {
fmt.Println("OnObjectUpdated() invalid message format:" + message)
return
}
serverID, _, objectID := s[0], s[1], s[2]
err := c.To("server"+serverID).Emit("objectupdate", objectID)
if err != nil {
fmt.Println(err, "failed to broacast object")
return
}
fmt.Println(fmt.Sprintf("OnObjectUpdated() message:%v, time taken: %v", message, time.Since(t)))
}
// OnDisconnect clean up things when a client is disconnected
func OnDisconnect(c websocket.Connection) {
c.Leave("server2")
fmt.Println("OnDisconnect(): client disconnected!")
}

View File

@@ -1,62 +0,0 @@
package main
import (
"fmt"
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
"gopkg.in/kataras/iris.v6/adaptors/websocket"
)
/* Native messages no need to import the iris-ws.js to the ./templates.client.html
Use of: OnMessage and EmitMessage.
NOTICE: IF YOU HAVE RAN THE PREVIOUS EXAMPLES YOU HAVE TO CLEAR YOUR BROWSER's CACHE
BECAUSE chat.js is different than the CACHED. OTHERWISE YOU WILL GET Ws is undefined from the browser's console, becuase it will use the cached.
*/
type clientPage struct {
Title string
Host string
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
ws := websocket.New(websocket.Config{
// the path which the websocket client should listen/registered to,
Endpoint: "/my_endpoint",
// to enable binary messages (useful for protobuf):
// BinaryMessages: true,
})
app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
app.StaticWeb("/js", "./static/js") // serve our custom javascript code
app.Get("/", func(ctx *iris.Context) {
ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
})
ws.OnConnection(func(c websocket.Connection) {
c.OnMessage(func(data []byte) {
message := string(data)
c.To(websocket.Broadcast).EmitMessage([]byte("Message from: " + c.ID() + "-> " + message)) // broadcast to all clients except this
c.EmitMessage([]byte("Me: " + message)) // writes to itself
})
c.OnDisconnect(func() {
fmt.Printf("\nConnection with ID: %s has been disconnected!", c.ID())
})
})
app.Listen(":8080")
}

View File

@@ -1,38 +0,0 @@
var messageTxt;
var messages;
$(function () {
messageTxt = $("#messageTxt");
messages = $("#messages");
w = new WebSocket("ws://" + HOST + "/my_endpoint");
w.onopen = function () {
console.log("Websocket connection enstablished");
};
w.onclose = function () {
appendMessage($("<div><center><h3>Disconnected</h3></center></div>"));
};
w.onmessage = function(message){
appendMessage($("<div>" + message.data + "</div>"));
};
$("#sendBtn").click(function () {
w.send(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;
}
}

View File

@@ -1,21 +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" type="text/javascript"></script>
<script src="js/chat.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -1,197 +0,0 @@
package main
import (
"fmt" // optional
"io/ioutil" // optional
"os" // optional
"time" // optional
"gopkg.in/kataras/iris.v6"
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
"gopkg.in/kataras/iris.v6/adaptors/view"
"gopkg.in/kataras/iris.v6/adaptors/websocket"
)
type clientPage struct {
Title string
Host string
}
func main() {
app := iris.New()
app.Adapt(iris.DevLogger()) // enable all (error) logs
app.Adapt(httprouter.New()) // select the httprouter as the servemux
app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
ws := websocket.New(websocket.Config{
// the path which the websocket client should listen/registered to,
Endpoint: "/my_endpoint",
// the client-side javascript static file path
// which will be served by Iris.
// default is /iris-ws.js
// if you change that you have to change the bottom of templates/client.html
// script tag:
ClientSourcePath: "/iris-ws.js",
//
// Set the timeouts, 0 means no timeout
// websocket has more configuration, go to ../../config.go for more:
// WriteTimeout: 0,
// ReadTimeout: 0,
// by-default all origins are accepted, you can change this behavior by setting:
// CheckOrigin: (r *http.Request ) bool {},
//
//
// 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 *iris.Context) string {},
})
app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
app.StaticWeb("/js", "./static/js") // static route to serve our javascript files
app.Get("/", func(ctx *iris.Context) {
// send our custom javascript source file before client really asks for that
// using the new go v1.8's HTTP/2 Push.
// Note that you have to listen using ListenTLS in order this to work.
if err := ctx.Push("/js/chat.js", nil); err != nil {
app.Log(iris.DevMode, err.Error())
}
ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
})
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.Framework) {
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)
// add an event when control+C pressed, to remove the temp cert and key files.
app.Adapt(iris.EventPolicy{
Interrupted: func(*iris.Framework) {
certFile.Close()
time.Sleep(50 * time.Millisecond)
os.Remove(certFile.Name())
keyFile.Close()
time.Sleep(50 * time.Millisecond)
os.Remove(keyFile.Name())
},
})
// https://localhost
app.ListenTLS("localhost:443", certFile.Name(), keyFile.Name())
}

View File

@@ -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;
}
}

View File

@@ -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>