1
0
mirror of https://github.com/kataras/iris.git synced 2026-05-07 22:53:46 +00:00

Add notes for the new lead maintainer of the open-source iris project and align with @get-ion/ion by @hiveminded

Former-commit-id: da4f38eb9034daa49446df3ee529423b98f9b331
This commit is contained in:
kataras
2017-07-10 18:32:42 +03:00
parent 2d4c2779a7
commit 9f85b74fc9
344 changed files with 4842 additions and 5174 deletions

View File

@@ -1,110 +1,164 @@
# Examples
This folder provides easy to understand code snippets on how to get started with web development with the Go programming language using the [Iris](https://github.com/kataras/iris) web framework.
Please do learn how [net/http](https://golang.org/pkg/net/http/) std package works, first.
It doesn't contains "best ways" neither explains all its features. It's just a simple, practical cookbook for young Gophers!
This folder provides easy to understand code snippets on how to get started with [iris](https://github.com/kataras/iris) micro web framework.
## Table of contents
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!
* [Level: Beginner](beginner)
* [Hello world](beginner/hello-world/main.go)
* [Overview](beginner/overview/main.go)
* [Listening](beginner/listening)
* [Common, with address](beginner/listening/listen-addr/main.go)
* [UNIX socket file](beginner/listening/listen-unix/main.go)
* [TLS](beginner/listening/listen-tls/main.go)
* [Letsencrypt (Automatic Certifications)](beginner/listening/listen-letsencrypt/main.go)
* [Custom TCP Listener](beginner/listening/custom-listener/main.go)
* [Configuration](beginner/configuration)
* [Basic way](beginner/configuration/basic/main.go)
* [Functional way](beginner/configuration/functional/main.go)
* [Import from YAML file](beginner/configuration/from-yaml-file/main.go)
* [Import from TOML file](beginner/configuration/from-toml-file/main.go)
* [Routing](beginner/routing)
* [Overview](beginner/routing/overview/main.go)
* [Basic](beginner/routing/basic/main.go)
* [Dynamic Path](beginner/routing/dynamic-path/main.go)
* [Reverse routing](beginner/routing/reverse/main.go)
* [Custom wrapper](beginner/routing/custom-wrapper/main.go)
* [Transform any third-party handler to iris-compatible handler](beginner/convert-handlers)
* [From func(http.ResponseWriter, *http.Request, http.HandlerFunc)](beginner/convert-handlers/negroni-like/main.go)
* [From http.Handler or http.HandlerFunc](beginner/convert-handlers/nethttp/main.go)
* [Internal Application File Logger](beginner/file-logger/main.go)
* [Custom HTTP Errors](beginner/http-errors/main.go)
* [Write JSON](beginner/write-json/main.go)
* [Read JSON](beginner/read-json/main.go)
* [Read Form](beginner/read-form/main.go)
* [Favicon](beginner/favicon/main.go)
* [File Server](beginner/file-server)
* [Basic](beginner/file-server/basic/main.go)
* [Embedding Files Into App Executable File](beginner/file-server/embedding-files-into-app/main.go)
* [Single Page Application](beginner/file-server/single-page-application/main.go)
* [Embedding Single Page Application](beginner/file-server/embedding-single-page-application/main.go)
* [Send Files](beginner/send-files/main.go)
* [Stream Writer](beginner/stream-writer/main.go)
* [Send An E-mail](beginner/e-mail/main.go)
* [Upload/Read Files](beginner/upload-files/main.go)
* [Recovery](beginner/recover/main.go)
* [Profiling (pprof)](beginner/pprof/main.go)
* [Request Logger](beginner/request-logger/main.go)
* [Basic Authentication](beginner/basicauth/main.go)
* [Level: Intermediate](intermediate)
* [JWT](https://github.com/iris-contrib/middleware/blob/master/jwt/_example/main.go)
* [OAUth2](intermediate/oauth2/main.go)
* [CORS](https://github.com/iris-contrib/middleware/blob/master/cors/_example/main.go)
* [Transactions](intermediate/transactions/main.go)
* [HTTP Testing](intermediate/httptest/main_test.go)
* [Watch & Compile Typescript source files](intermediate/typescript/main.go)
* [Cloud Editor](intermediate/cloud-editor/main.go)
* [HTTP Access Control](intermediate/cors/main.go)
* [Cache Markdown](intermediate/cache-markdown/main.go)
* [Localization and Internationalization](intermediate/i18n/main.go)
* [Graceful Shutdown](intermediate/graceful-shutdown)
* [Basic and simple](intermediate/graceful-shutdown/basic/main.go)
* [Custom Host](intermediate/graceful-shutdown/custom-host/main.go)
* [Custom notifier](intermediate/graceful-shutdown/custom-notifier/main.go)
* [Custom HTTP Server](intermediate/custom-httpserver)
* [Iris way](intermediate/custom-httpserver/iris-way/main.go)
* [Standar way](intermediate/custom-httpserver/std-way/main.go)
* [More than one server](intermediate/custom-httpserver/multi/main.go)
* [Custom Context](intermediate/custom-context)
* [Method Overriding](intermediate/custom-context/method-overriding/main.go)
* [Route State](intermediate/route-state/main.go)
* [View Engine](intermediate/view)
* [Overview](intermediate/view/overview/main.go)
* [Hi](intermediate/view/template_html_0/main.go)
* [Showcase one simple Layout](intermediate/view/template_html_1/main.go)
* [Layouts `yield` and `render` tmpl funcs](intermediate/view/template_html_2/main.go)
* [Showcase of the `urlpath` tmpl func](intermediate/view/template_html_3/main.go)
* [Showcase of the `url` tmpl func](intermediate/view/template_html_4/main.go)
* [Inject Data Between Handlers](intermediate/view/context-view-data/main.go)
* [Embedding Templates Into App Executable File](intermediate/view/embedding-templates-into-app/main.go)
* [Sessions](intermediate/sessions)
* [Overview](intermediate/sessions/overview/main.go)
* [Encoding & Decoding the Session ID: Secure Cookie](intermediate/sessions/securecookie/main.go)
* [Standalone](intermediate/sessions/standalone/main.go)
* [Flash Messages](intermediate/sessions/flash-messages/main.go)
* [With A Back-End Database](intermediate/sessions/database/main.go)
* [Password Hashing](intermediate/sessions/password-hashing/main.go)
* [Websockets](intermediate/websockets)
* [Ridiculous Simple](intermediate/websockets/ridiculous-simple/main.go)
* [Overview](intermediate/websockets/overview/main.go)
* [Connection List](intermediate/websockets/connectionlist/main.go)
* [Native Messages](intermediate/websockets/native-messages/main.go)
* [Secure](intermediate/websockets/secure/main.go)
* [Custom Go Client](intermediate/websockets/custom-go-client/main.go)
* [Subdomains](intermediate/subdomains)
* [Single](intermediate/subdomains/single/main.go)
* [Multi](intermediate/subdomains/multi/main.go)
* [Wildcard](intermediate/subdomains/wildcard/main.go)
* [WWW](intermediate/subdomains/www/main.go)
* [Level: Advanced](advanced)
* [Online Visitors](advanced/online-visitors/main.go)
* [URL Shortener using BoltDB](advanced/url-shortener/main.go)
### Overview
- [Hello world!](hello-world/main.go)
- [Glimpse](overview/main.go)
- [Tutorial: Online Visitors](tutorial/online-visitors/main.go)
- [Tutorial: URL Shortener using BoltDB](tutorial/url-shortener/main.go)
### HTTP Listening
- [Common, with address](http-listening/listen-addr/main.go)
- [UNIX socket file](http-listening/listen-unix/main.go)
- [TLS](http-listening/listen-tls/main.go)
- [Letsencrypt (Automatic Certifications)](http-listening/listen-letsencrypt/main.go)
- Custom TCP Listener
* [common net.Listener](http-listening/custom-listener/main.go)
* [SO_REUSEPORT for unix systems](http-listening/custom-listener/unix-reuseport/main.go)
- Custom HTTP Server
* [iris way](http-listening/custom-httpserver/iris-way/main.go)
* [std way](http-listening/custom-httpserver/std-way/main.go)
* [multi server instances](http-listening/custom-httpserver/multi/main.go)
- Graceful Shutdown
* [using the `RegisterOnInterrupt`](http-listening/graceful-shutdown/default-notifier/main.go)
* [using a custom notifier](http-listening/graceful-shutdown/custom-notifier/main.go)
### Configuration
- [Functional](configuration/functional/main.go)
- [From Configuration Struct](configuration/from-configuration-struct/main.go)
- [Import from YAML file](configuration/from-yaml-file/main.go)
- [Import from TOML file](configuration/from-toml-file/main.go)
You may want to check out examples for jwt, cors and the rest of community-maden middleware by clicking [here](https://github.com/iris-contrib/middleware)
### Routing, Grouping, Dynamic Path Parameters, "Macros" and Custom Context
- [Overview](routing/overview/main.go)
- [Basic](routing/basic/main.go)
- [Custom HTTP Errors](routing/http-errors/main.go)
- [Dynamic Path](routing/dynamic-path/main.go)
- [Reverse routing](routing/reverse/main.go)
- [Custom wrapper](routing/custom-wrapper/main.go)
- Custom Context
* [Method Overriding](routing/custom-context/method-overriding/main.go)
* [New Implementation](routing/custom-context/new-implementation/main.go)
- [Route State](routing/route-state/main.go)
### Subdomains
- [Single](subdomains/single/main.go)
- [Multi](subdomains/multi/main.go)
- [Wildcard](subdomains/wildcard/main.go)
- [WWW](subdomains/www/main.go)
### Convert `http.Handler/HandlerFunc`
- [From func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)](convert-handlers/negroni-like/main.go)
- [From http.Handler or http.HandlerFunc](convert-handlers/nethttp/main.go)
### View
| Engine | Declaration |
| -----------|-------------|
| template/html | `iris.HTML(...)` |
| django | `iris.Django(...)` |
| handlebars | `iris.Handlebars(...)` |
| amber | `iris.Amber(...)` |
| pug(jade) | `iris.Pug(...)` |
- [Overview](view/overview/main.go)
- [Hi](view/template_html_0/main.go)
- [A simple Layout](view/template_html_1/main.go)
- [Layouts: `yield` and `render` tmpl funcs](view/template_html_2/main.go)
- [The `urlpath` tmpl func](view/template_html_3/main.go)
- [The `url` tmpl func](view/template_html_4/main.go)
- [Inject Data Between Handlers](view/context-view-data/main.go)
- [Embedding Templates Into App Executable File](view/embedding-templates-into-app/main.go)
### Authentication
- [Basic Authentication](authentication/basicauth/main.go)
- [OAUth2](authentication/oauth2/main.go)
- [JWT](https://github.com/iris-contrib/middleware/blob/master/jwt/_example/main.go)
- [Sessions](#sessions)
### File Server
- [Favicon](file-server/favicon/main.go)
- [Basic](file-server/basic/main.go)
- [Embedding Files Into App Executable File](file-server/embedding-files-into-app/main.go)
- [Send/Force-Download Files](file-server/send-files/main.go)
- Single Page Applications
* [Single Page Application](file-server/single-page-application/basic/main.go)
* [Embedded Single Page Application](file-server/single-page-application/embedded-single-page-application/main.go)
### How to Read from `context.Request() *http.Request`
- [Bind JSON](http_request/read-json/main.go)
- [Bind Form](http_request/read-form/main.go)
- [Upload/Read Files](http_request/upload-files/main.go)
> The `context.Request()` returns the same *http.Request you already know, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
### How to Write to `context.ResponseWriter() http.ResponseWriter`
- [Text, Markdown, HTML, JSON, JSONP, XML, Binary](http_responsewriter/write-rest/main.go)
- [Stream Writer](http_responsewriter/stream-writer/main.go)
- [Transactions](http_responsewriter/transactions/main.go)
> The `context.ResponseWriter()` returns an enchament version of a http.ResponseWriter, these examples show some places where the Context uses this object. Besides that you can use it as you did before iris.
### Miscellaneous
- [Request Logger](http_request/request-logger/main.go)
- [Localization and Internationalization](miscellaneous/i18n/main.go)
- [Recovery](miscellaneous/recover/main.go)
- [Profiling (pprof)](miscellaneous/pprof/main.go)
- [Internal Application File Logger](miscellaneous/file-logger/main.go)
#### More
https://github.com/kataras/iris/tree/master/middleware#third-party-handlers
### Testing
The `httptest` package is your way for end-to-end HTTP testing, it uses the httpexpect library created by our friend, [gavv](https://github.com/gavv).
[Example](testing/httptest/main_test.go)
### Caching
iris cache library lives on its own package: [https://github.com/kataras/iris/tree/master/cache](https://github.com/kataras/iris/tree/master/cache) **it contains examples**
### Sessions
iris session manager lives on its own package: [https://github.com/kataras/iris/tree/master/sessions](https://github.com/kataras/iris/tree/master/sessions) **it contains examples**
> You're free to use your own favourite sessions package if you'd like so.
### Websockets
iris websocket library lives on its own package: [https://github.com/kataras/iris/tree/master/websocket](https://github.com/kataras/iris/tree/master/websocket) **it contains examples**
> You're free to use your own favourite websockets package if you'd like so.
### Typescript Automation Tools
typescript automation tools have their own repository: [https://github.com/kataras/iris/tree/master/typescript](https://github.com/kataras/iris/tree/master/typescript) **it contains examples**
> I'd like to tell you that you can use your favourite but I don't think you will find such a thing anywhere else.
### Hey, You!
Developers should read the [godocs](https://godoc.org/github.com/kataras/iris) for a better understanding.
Psst, I almost forgot; do not forget to [star or watch](https://github.com/kataras/iris/stargazers) the project in order to stay updated with the latest tech trends, it never takes more than a second!
> Do not forget to [star or watch the project](https://github.com/kataras/iris/stargazers) in order to stay updated with the latest tech trends, it takes some seconds for the sake of go!
> Developers should read the official [documentation](https://godoc.org/github.com/kataras/iris) in depth, for deep understanding.

View File

@@ -1,4 +0,0 @@
package main
// Version is the current version of the url-shortener package.
const Version = "0.0.1"

View File

@@ -0,0 +1,6 @@
# Authentication
- [Basic Authentication](basicauth/main.go)
- [OAUth2](oauth2/main.go)
- [JWT](https://github.com/iris-contrib/middleware/blob/master/jwt/_example/main.go)
- [Sessions](https://github.com/kataras/iris/tree/master/_examples/#sessions)

View File

@@ -8,7 +8,7 @@ import (
"github.com/kataras/iris/middleware/basicauth"
)
func main() {
func newApp() *iris.Application {
app := iris.New()
authConfig := basicauth.Config{
@@ -40,6 +40,11 @@ func main() {
needAuth.Get("/settings", h)
}
return app
}
func main() {
app := newApp()
// open http://localhost:8080/admin
app.Run(iris.Addr(":8080"))
}

View File

@@ -0,0 +1,29 @@
package main
import (
"testing"
"github.com/kataras/iris/httptest"
)
func TestBasicAuth(t *testing.T) {
app := newApp()
e := httptest.New(t, app)
// redirects to /admin without basic auth
e.GET("/").Expect().Status(httptest.StatusUnauthorized)
// without basic auth
e.GET("/admin").Expect().Status(httptest.StatusUnauthorized)
// with valid basic auth
e.GET("/admin").WithBasicAuth("myusername", "mypassword").Expect().
Status(httptest.StatusOK).Body().Equal("/admin myusername:mypassword")
e.GET("/admin/profile").WithBasicAuth("myusername", "mypassword").Expect().
Status(httptest.StatusOK).Body().Equal("/admin/profile myusername:mypassword")
e.GET("/admin/settings").WithBasicAuth("myusername", "mypassword").Expect().
Status(httptest.StatusOK).Body().Equal("/admin/settings myusername:mypassword")
// with invalid basic auth
e.GET("/admin/settings").WithBasicAuth("invalidusername", "invalidpassword").
Expect().Status(httptest.StatusUnauthorized)
}

View File

@@ -1,7 +1,7 @@
package main
// Any OAuth2 (even the pure golang/x/net/oauth2) package
// can be used with Iris but at this example we will see the markbates' goth:
// can be used with iris but at this example we will see the markbates' goth:
//
// $ go get github.com/markbates/goth/...
//
@@ -26,8 +26,8 @@ import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
"github.com/kataras/iris/view"
"github.com/gorilla/securecookie" // optionally, used for session's encoder/decoder
@@ -70,6 +70,24 @@ import (
"github.com/markbates/goth/providers/yammer"
)
var sessionsManager *sessions.Sessions
func init() {
// attach a session manager
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)
sessionsManager = sessions.New(sessions.Config{
Cookie: cookieName,
Encode: secureCookie.Encode,
Decode: secureCookie.Decode,
})
}
// These are some function helpers that you may use if you want
// GetProviderName is a function used to get the name of a provider
@@ -97,7 +115,7 @@ var GetProviderName = func(ctx context.Context) (string, error) {
}
/*
BeginAuthHandler is a convienence handler for starting the authentication process.
BeginAuthHandler is a convenience handler for starting the authentication process.
It expects to be able to get the name of the provider from the query parameters
as either "provider" or ":provider".
@@ -146,8 +164,8 @@ func GetAuthURL(ctx context.Context) (string, error) {
if err != nil {
return "", err
}
ctx.Session().Set(providerName, sess.Marshal())
session := sessionsManager.Start(ctx)
session.Set(providerName, sess.Marshal())
return url, nil
}
@@ -191,8 +209,8 @@ var CompleteUserAuth = func(ctx context.Context) (goth.User, error) {
if err != nil {
return goth.User{}, err
}
value := ctx.Session().GetString(providerName)
session := sessionsManager.Start(ctx)
value := session.GetString(providerName)
if value == "" {
return goth.User{}, errors.New("session value for " + providerName + " not found")
}
@@ -214,7 +232,7 @@ var CompleteUserAuth = func(ctx context.Context) (goth.User, error) {
return goth.User{}, err
}
ctx.Session().Set(providerName, sess.Marshal())
session.Set(providerName, sess.Marshal())
return provider.FetchUser(sess)
}
@@ -224,8 +242,8 @@ func Logout(ctx context.Context) error {
if err != nil {
return err
}
ctx.Session().Delete(providerName)
session := sessionsManager.Start(ctx)
session.Delete(providerName)
return nil
}
@@ -341,21 +359,7 @@ func main() {
app := iris.New()
// attach and build our templates
app.AttachView(view.HTML("./templates", ".html"))
// attach a session manager
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)
sessManager := sessions.New(sessions.Config{
Cookie: cookieName,
Encode: secureCookie.Encode,
Decode: secureCookie.Decode,
})
app.AttachSessionManager(sessManager)
app.RegisterView(iris.HTML("./templates", ".html"))
// start of the router

View File

@@ -1,87 +0,0 @@
package main
import (
"bytes"
"github.com/kataras/go-mailer"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/view"
)
func main() {
app := iris.New()
app.AttachView(view.HTML("./templates", ".html"))
// change these to your own settings
cfg := mailer.Config{
Host: "smtp.mailgun.org",
Username: "postmaster@sandbox661c307650f04e909150b37c0f3b2f09.mailgun.org",
Password: "38304272b8ee5c176d5961dc155b2417",
Port: 587,
}
// change these to your e-mail to check if that works
// create the service
mailService := mailer.New(cfg)
var to = []string{"kataras2006@hotmail.com"}
// standalone
//mailService.Send("iris e-mail test subject", "</h1>outside of context before server's listen!</h1>", to...)
//inside handler
app.Get("/send", func(ctx context.Context) {
content := `<h1>Hello From Iris web framework</h1> <br/><br/> <span style="color:blue"> This is the rich message body </span>`
err := mailService.Send("iris e-mail just t3st subject", content, to...)
if err != nil {
ctx.HTML("<b> Problem while sending the e-mail: " + err.Error())
} else {
ctx.HTML("<h1> SUCCESS </h1>")
}
})
// send a body by template
app.Get("/send/template", func(ctx context.Context) {
// we will not use ctx.View
// because we don't want to render to the client
// we need the templates' parsed result as raw bytes
// so we make use of the bytes.Buffer which is an io.Writer
// which being expected on app.View parameter first.
//
// the rest of the parameters are the same and the behavior is the same as ctx.View,
// except the 'where to render'
buff := &bytes.Buffer{}
// View executes and writes the result of a template file to the writer.
//
// First parameter is the writer to write the parsed template.
// Second parameter is the relative, to templates directory, template filename, including extension.
// Third parameter is the layout, can be empty string.
// Forth parameter is the bindable data to the template, can be nil.
//
// Use context.View to render templates to the client instead.
// Returns an error on failure, otherwise nil.
app.View(buff, "body.html", "", context.Map{
"Message": " his is the rich message body sent by a template!!",
"Footer": "The footer of this e-mail!",
})
content := buff.String()
err := mailService.Send("iris e-mail just t3st subject", content, to...)
if err != nil {
ctx.StatusCode(iris.StatusBadRequest)
ctx.HTML("<b> Sent failed with error: " + err.Error())
} else {
ctx.HTML("<h1> SUCCESS </h1>")
}
})
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,7 +0,0 @@
<h1>Hello From Iris web framework</h1>
<br />
<br />
<span style="color: red"> {{.Message}}</span>
<hr />
<b> {{.Footer}} </b>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,14 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.New()
app.Handle("GET", "/", func(ctx context.Context) {
ctx.HTML("<b> Hello world! </b>")
})
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,17 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/core/nettools"
)
func main() {
app := iris.New()
l, err := nettools.UNIX("/tmpl/srv.sock", 0666) // see its code to see how you can manually create a new file listener, it's easy.
if err != nil {
panic(err)
}
app.Run(iris.Listener(l))
}

View File

@@ -1,39 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
// User bind struct
type User struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
City string `json:"city"`
Age int `json:"age"`
}
func main() {
app := iris.New()
app.Post("/decode", func(ctx context.Context) {
var user User
ctx.ReadJSON(&user)
ctx.Writef("%s %s is %d years old and comes from %s!", user.Firstname, user.Lastname, user.Age, user.City)
})
app.Get("/encode", func(ctx context.Context) {
peter := User{
Firstname: "John",
Lastname: "Doe",
City: "Neither FBI knows!!!",
Age: 25,
}
ctx.StatusCode(iris.StatusOK)
ctx.JSON(peter)
})
app.Run(iris.Addr(":8080"))
}

View File

@@ -2,16 +2,19 @@ package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<b>Hello!</b>")
})
// [...]
// Good when you want to modify the whole configuration.
app.Run(iris.Addr(":8080"), iris.WithConfiguration(iris.Configuration{ // default configuration:
DisableBanner: false,
DisableStartupLog: false,
DisableInterruptHandler: false,
DisablePathCorrection: false,
EnablePathEscape: false,
@@ -22,7 +25,6 @@ func main() {
Charset: "UTF-8",
}))
// or before run:
// app.Configure(iris.WithConfiguration(...))
// app.Run(iris.Addr(":8080"))
// or before Run:
// app.Configure(iris.WithConfiguration(iris.Configuration{...}))
}

View File

@@ -6,4 +6,4 @@ TimeFormat = "Mon, 01 Jan 2006 15:04:05 GMT"
Charset = "UTF-8"
[Other]
MyServerName = "Iris"
MyServerName = "iris"

View File

@@ -2,11 +2,15 @@ package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<b>Hello!</b>")
})
// [...]
// Good when you have two configurations, one for development and a different one for production use.

View File

@@ -2,11 +2,14 @@ package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<b>Hello!</b>")
})
// [...]
// Good when you have two configurations, one for development and a different one for production use.

View File

@@ -2,15 +2,20 @@ package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<b>Hello!</b>")
})
// [...]
// Good when you want to change some of the configuration's field.
// I use that method :)
// Prefix: "With", code editors will help you navigate through all
// configuration options without even a glitch to the documentation.
app.Run(iris.Addr(":8080"), iris.WithoutBanner, iris.WithCharset("UTF-8"))
// or before run:

View File

@@ -5,13 +5,12 @@ import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/handlerconv"
)
func main() {
app := iris.New()
irisMiddleware := handlerconv.FromStdWithNext(negronilikeTestMiddleware)
app.Use(irisMiddleware)
ionMiddleware := iris.FromStd(negronilikeTestMiddleware)
app.Use(ionMiddleware)
// Method GET: http://localhost:8080/
app.Get("/", func(ctx context.Context) {
@@ -41,3 +40,6 @@ func negronilikeTestMiddleware(w http.ResponseWriter, r *http.Request, next http
w.WriteHeader(iris.StatusBadRequest)
w.Write([]byte("Bad request"))
}
// Look "routing/custom-context" if you want to convert a custom handler with a custom Context
// to a context.Handler.

View File

@@ -5,13 +5,12 @@ import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/handlerconv"
)
func main() {
app := iris.New()
irisMiddleware := handlerconv.FromStd(nativeTestMiddleware)
app.Use(irisMiddleware)
ionMiddleware := iris.FromStd(nativeTestMiddleware)
app.Use(ionMiddleware)
// Method GET: http://localhost:8080/
app.Get("/", func(ctx context.Context) {
@@ -31,3 +30,6 @@ func main() {
func nativeTestMiddleware(w http.ResponseWriter, r *http.Request) {
println("Request path: " + r.URL.Path)
}
// Look "routing/custom-context" if you want to convert a custom handler with a custom Context
// to a context.Handler.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -3,10 +3,10 @@ package main
import (
"io/ioutil"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/kataras/iris"
"github.com/kataras/iris/httptest"
)
@@ -33,7 +33,11 @@ func (r resource) loadFromBase(dir string) string {
panic(fullpath + " failed with error: " + err.Error())
}
return string(b)
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
}
return result
}
var urls = []resource{
@@ -49,12 +53,18 @@ func TestEmbeddingFilesIntoApp(t *testing.T) {
app := newApp()
e := httptest.New(t, app)
if runtime.GOOS != "windows" {
// remove the embedded static favicon for !windows,
// it should be built for unix-specific in order to be work
urls = urls[0 : len(urls)-1]
}
for _, u := range urls {
url := u.String()
contents := u.loadFromBase("./assets")
e.GET(url).Expect().
Status(iris.StatusOK).
Status(httptest.StatusOK).
Body().Equal(contents)
}
}

View File

@@ -8,17 +8,17 @@ import (
func main() {
app := iris.New()
// This will serve the ./static/favicons/iris_favicon_48_48.ico to: localhost:8080/favicon.ico
app.Favicon("./static/favicons/iris_favicon_48_48.ico")
// This will serve the ./static/favicons/favicon.ico to: localhost:8080/favicon.ico
app.Favicon("./static/favicons/favicon.ico.ico")
// app.Favicon("./static/favicons/iris_favicon_48_48.ico", "/favicon_48_48.ico")
// This will serve the ./static/favicons/iris_favicon_48_48.ico to: localhost:8080/favicon_48_48.ico
// app.Favicon("./static/favicons/favicon.ico.ico", "/favicon_16_16.ico")
// This will serve the ./static/favicons/favicon.ico.ico to: localhost:8080/favicon_16_16.ico
app.Get("/", func(ctx context.Context) {
ctx.HTML(`<a href="/favicon.ico"> press here to see the favicon.ico</a>.
At some browsers like chrome, it should be visible at the top-left side of the browser's window,
because some browsers make requests to the /favicon.ico automatically,
so Iris serves your favicon in that path too (you can change it).`)
so iris serves your favicon in that path too (you can change it).`)
}) // if favicon doesn't show to you, try to clear your browser's cache.
app.Run(iris.Addr(":8080"))

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -6,7 +6,7 @@ import (
"github.com/kataras/iris/view"
)
// same as embedding-single-page-application but without go-bindata, the files are "physical" stored in the
// same as embedded-single-page-application but without go-bindata, the files are "physical" stored in the
// current system directory.
var page = struct {
@@ -15,7 +15,7 @@ var page = struct {
func newApp() *iris.Application {
app := iris.New()
app.AttachView(view.HTML("./public", ".html"))
app.RegisterView(view.HTML("./public", ".html"))
app.Get("/", func(ctx context.Context) {
ctx.ViewData("Page", page)

View File

@@ -6,7 +6,6 @@ import (
"strings"
"testing"
"github.com/kataras/iris"
"github.com/kataras/iris/httptest"
)
@@ -35,7 +34,8 @@ func (r resource) loadFromBase(dir string) string {
panic(fullpath + " failed with error: " + err.Error())
}
return string(b)
result := string(b)
return result
}
var urls = []resource{
@@ -47,7 +47,7 @@ var urls = []resource{
func TestSPA(t *testing.T) {
app := newApp()
e := httptest.New(t, app)
e := httptest.New(t, app, httptest.Debug(true))
for _, u := range urls {
url := u.String()
@@ -55,7 +55,7 @@ func TestSPA(t *testing.T) {
contents = strings.Replace(contents, "{{ .Page.Title }}", page.Title, 1)
e.GET(url).Expect().
Status(iris.StatusOK).
Status(httptest.StatusOK).
Body().Equal(contents)
}
}

View File

@@ -182,9 +182,9 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
"public/app.js": publicAppJs,
"public/app.js": publicAppJs,
"public/css/main.css": publicCssMainCss,
"public/index.html": publicIndexHtml,
"public/index.html": publicIndexHtml,
}
// AssetDir returns the file names below a certain
@@ -226,13 +226,14 @@ type bintree struct {
Func func() (*asset, error)
Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
"public": &bintree{nil, map[string]*bintree{
"app.js": &bintree{publicAppJs, map[string]*bintree{}},
"css": &bintree{nil, map[string]*bintree{
"main.css": &bintree{publicCssMainCss, map[string]*bintree{}},
"public": {nil, map[string]*bintree{
"app.js": {publicAppJs, map[string]*bintree{}},
"css": {nil, map[string]*bintree{
"main.css": {publicCssMainCss, map[string]*bintree{}},
}},
"index.html": &bintree{publicIndexHtml, map[string]*bintree{}},
"index.html": {publicIndexHtml, map[string]*bintree{}},
}},
}}
@@ -282,4 +283,3 @@ func _filePath(dir, name string) string {
cannonicalName := strings.Replace(name, "\\", "/", -1)
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

View File

@@ -9,7 +9,7 @@ import (
// $ go get -u github.com/jteeuwen/go-bindata/...
// $ go-bindata ./public/...
// $ go build
// $ ./embedding-single-page-application
// $ ./embedded-single-page-application
var page = struct {
Title string
@@ -17,7 +17,7 @@ var page = struct {
func newApp() *iris.Application {
app := iris.New()
app.AttachView(view.HTML("./public", ".html").Binary(Asset, AssetNames))
app.RegisterView(view.HTML("./public", ".html").Binary(Asset, AssetNames))
app.Get("/", func(ctx context.Context) {
ctx.ViewData("Page", page)

View File

@@ -3,10 +3,10 @@ package main
import (
"io/ioutil"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/kataras/iris"
"github.com/kataras/iris/httptest"
)
@@ -34,8 +34,11 @@ func (r resource) loadFromBase(dir string) string {
if err != nil {
panic(fullpath + " failed with error: " + err.Error())
}
return string(b)
result := string(b)
if runtime.GOOS != "windows" {
result = strings.Replace(result, "\n", "\r\n", -1)
}
return result
}
var urls = []resource{
@@ -55,7 +58,7 @@ func TestSPAEmbedded(t *testing.T) {
contents = strings.Replace(contents, "{{ .Page.Title }}", page.Title, 1)
e.GET(url).Expect().
Status(iris.StatusOK).
Status(httptest.StatusOK).
Body().Equal(contents)
}
}

View File

@@ -0,0 +1,36 @@
// +build go.1.8
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
func main() {
app := iris.Default()
// Method: GET
// Resource: http://localhost:8080/
app.Handle("GET", "/", func(ctx context.Context) {
ctx.HTML("<b>Hello world!</b>")
})
// same as app.Handle("GET", "/ping", [...])
// Method: GET
// Resource: http://context:8080/ping
app.Get("/ping", func(ctx iris.Context) {
ctx.WriteString("pong")
})
// Method: GET
// Resource: http://localhost:8080/hello
app.Get("/hello", func(ctx context.Context) {
ctx.JSON(iris.Map{"message": "Hello iris web framework."})
})
// http://localhost:8080
// http://localhost:8080/ping
// http://localhost:8080/hello
app.Run(iris.Addr(":8080"))
}

View File

@@ -0,0 +1,35 @@
// +build go1.9
package main
import (
"github.com/kataras/iris"
)
func main() {
app := iris.Default()
// Method: GET
// Resource: http://localhost:8080/
app.Handle("GET", "/", func(ctx iris.Context) {
ctx.HTML("<b>Hello world!</b>")
})
// same as app.Handle("GET", "/ping", [...])
// Method: GET
// Resource: http://localhost:8080/ping
app.Get("/ping", func(ctx iris.Context) {
ctx.WriteString("pong")
})
// Method: GET
// Resource: http://localhost:8080/hello
app.Get("/hello", func(ctx iris.Context) {
ctx.JSON(iris.Map{"message": "Hello iris web framework."})
})
// http://localhost:8080
// http://localhost:8080/ping
// http://localhost:8080/hello
app.Run(iris.Addr(":8080"))
}

View File

@@ -18,7 +18,9 @@ func main() {
ctx.Writef("Hello from %s", ctx.Path())
})
srv := &http.Server{Addr: ":8080" /* Any custom fields here: Handler and ErrorLog are setted to the server automatically */}
// Any custom fields here. Handler and ErrorLog are setted to the server automatically
srv := &http.Server{Addr: ":8080"}
// http://localhost:8080/
// http://localhost:8080/mypath
app.Run(iris.Server(srv)) // same as app.Run(iris.Addr(":8080"))

View File

@@ -18,10 +18,8 @@ func main() {
ctx.Writef("Hello from %s", ctx.Path())
})
// call .Build before use the 'app' as an http.Handler on a custom http.Server
if err := app.Build(); err != nil {
panic(err)
}
// call .Build before use the 'app' as a http.Handler on a custom http.Server
app.Build()
// create our custom server and assign the Handler/Router
srv := &http.Server{Handler: app, Addr: ":8080"} // you have to set Handler:app and Addr, see "iris-way" which does this automatically.

View File

@@ -0,0 +1,45 @@
// +build linux darwin dragonfly freebsd netbsd openbsd rumprun
package main
import (
// Package tcplisten provides customizable TCP net.Listener with various
// performance-related options:
//
// - SO_REUSEPORT. This option allows linear scaling server performance
// on multi-CPU servers.
// See https://www.nginx.com/blog/socket-sharding-nginx-release-1-9-1/ for details.
//
// - TCP_DEFER_ACCEPT. This option expects the server reads from the accepted
// connection before writing to them.
//
// - TCP_FASTOPEN. See https://lwn.net/Articles/508865/ for details.
"github.com/valyala/tcplisten"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
// $ go get github.com/valyala/tcplisten
// $ go run main.go
func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<b>Hello World!</b>")
})
listenerCfg := tcplisten.Config{
ReusePort: true,
DeferAccept: true,
FastOpen: true,
}
l, err := listenerCfg.NewListener("tcp", ":8080")
if err != nil {
panic(err)
}
app.Run(iris.Listener(l))
}

View File

@@ -0,0 +1,7 @@
// +build windows
package main
func main() {
panic("windows operating system does not support this feature")
}

View File

@@ -13,10 +13,9 @@ import (
func main() {
app := iris.New()
// output startup banner and error logs on os.Stdout
app.Get("/", func(ctx context.Context) {
ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>")
ctx.HTML("<h1>hi, I just exist in order to see if the server is closed</h1>")
})
go func() {
@@ -33,16 +32,16 @@ func main() {
)
select {
case <-ch:
println("Shutdown the server gracefully...")
println("shutdown...")
timeout := 5 * time.Second // give the server 5 seconds to wait for idle connections.
timeout := 5 * time.Second
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
defer cancel()
app.Shutdown(ctx)
}
}()
// Start the server and disable the default interrupt handler in order to handle it clear and simple by our own, without
// any issues.
// Start the server and disable the default interrupt handler in order to
// handle it clear and simple by our own, without any issues.
app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler)
}

View File

@@ -0,0 +1,35 @@
package main
import (
stdContext "context"
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
// Before continue:
//
// Gracefully Shutdown on control+C/command+C or when kill command sent is ENABLED BY-DEFAULT.
//
// In order to manually manage what to do when app is interrupted,
// We have to disable the default behavior with the option `WithoutInterruptHandler`
// and register a new interrupt handler (globally, across all possible hosts).
func main() {
app := iris.New()
iris.RegisterOnInterrupt(func() {
timeout := 5 * time.Second
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
defer cancel()
// close all hosts
app.Shutdown(ctx)
})
app.Get("/", func(ctx context.Context) {
ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>")
})
// http://localhost:8080
app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler)
}

View File

@@ -9,7 +9,7 @@ func main() {
app := iris.New()
app.Get("/", func(ctx context.Context) {
ctx.HTML("<h1>Index /</h1>")
ctx.HTML("<h1>Hello World!/</h1>")
})
if err := app.Run(iris.Addr(":8080")); err != nil {

View File

@@ -22,7 +22,7 @@ func main() {
})
// If http to https auto-redirect is one of your needs
// please look the code inside iris_deprecateed.go.ListenLETSENCRYPT to do it manually.
// please look the code inside ion_deprecateed.go.ListenLETSENCRYPT to do it manually.
// NOTE: This may not work on local addresses like this,
// use it on a real domain, because

View File

@@ -0,0 +1,19 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/core/netutil"
)
func main() {
app := iris.New()
l, err := netutil.UNIX("/tmpl/srv.sock", 0666) // see its code to see how you can manually create a new file listener, it's easy.
if err != nil {
panic(err)
}
app.Run(iris.Listener(l))
}
// Look "custom-listener/unix-reuseport" too.

View File

@@ -0,0 +1 @@
The `context.Request()` returns the same *http.Request you already know, the examples show some places where the Context uses this object. Besides that you can use it as you did before iris.

View File

@@ -17,7 +17,7 @@ func main() {
app := iris.New()
// set the view html template engine
app.AttachView(view.HTML("./templates", ".html").Reload(true))
app.RegisterView(view.HTML("./templates", ".html").Reload(true))
app.Get("/", func(ctx context.Context) {
if err := ctx.View("form.html"); err != nil {

View File

@@ -31,7 +31,7 @@ func main() {
// to the http://localhost:8080 with RAW BODY:
/*
{
"Name": "Iris-Go",
"Name": "iris-Go",
"City": "New York",
"Other": "Something here"
}
@@ -39,6 +39,6 @@ func main() {
// and Content-Type to application/json
//
// The response should be:
// Received: &main.Company{Name:"Iris-Go", City:"New York", Other:"Something here"}
// Received: &main.Company{Name:"iris-Go", City:"New York", Other:"Something here"}
app.Run(iris.Addr(":8080"))
}

View File

@@ -16,7 +16,7 @@ import (
func main() {
app := iris.New()
app.AttachView(view.HTML("./templates", ".html"))
app.RegisterView(view.HTML("./templates", ".html"))
// Serve the form.html to the user
app.Get("/upload", func(ctx context.Context) {

View File

@@ -0,0 +1 @@
The `context.ResponseWriter()` returns an enchament version of a http.ResponseWriter, the examples show some places where the Context uses this object. Besides that you can use it as you did before iris.

View File

@@ -32,7 +32,7 @@ func main() {
// OPTIONAl STEP:
// but useful if we want to post back an error message to the client if the transaction failed.
// if the reason is empty then the transaction completed succesfuly,
// if the reason is empty then the transaction completed successfully,
// otherwise we rollback the whole response writer's body,
// headers and cookies, status code and everything lives inside this transaction
t.Complete(err)

View File

@@ -5,9 +5,16 @@ import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/view"
)
// User bind struct
type User struct {
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
City string `json:"city"`
Age int `json:"age"`
}
// ExampleXML just a test struct to view represents xml content-type
type ExampleXML struct {
XMLName xml.Name `xml:"example"`
@@ -18,8 +25,32 @@ type ExampleXML struct {
func main() {
app := iris.New()
// Just some general restful render types, none of these has to do anything with templates.
app.Get("/binary", func(ctx context.Context) { // useful when you want force-download of contents of raw bytes form.
// Read
app.Post("/decode", func(ctx context.Context) {
var user User
ctx.ReadJSON(&user)
ctx.Writef("%s %s is %d years old and comes from %s!", user.Firstname, user.Lastname, user.Age, user.City)
})
// Write
app.Get("/encode", func(ctx context.Context) {
peter := User{
Firstname: "John",
Lastname: "Doe",
City: "Neither FBI knows!!!",
Age: 25,
}
ctx.StatusCode(iris.StatusOK)
// Manually setting a content type: ctx.ContentType("application/javascript")
ctx.JSON(peter)
})
// Other content types,
app.Get("/binary", func(ctx context.Context) {
// useful when you want force-download of contents of raw bytes form.
ctx.Binary([]byte("Some binary data here."))
})
@@ -40,38 +71,17 @@ func main() {
})
app.Get("/markdown", func(ctx context.Context) {
ctx.Markdown([]byte("# Hello Dynamic Markdown -- Iris"))
ctx.Markdown([]byte("# Hello Dynamic Markdown -- iris"))
})
// http://localhost:8080/decode
// http://localhost:8080/encode
//
// - standard html | view.HTML(...)
// - django | view.Django(...)
// - pug(jade) | view.Pug(...)
// - handlebars | view.Handlebars(...)
// - amber | view.Amber(...)
// with default template funcs:
//
// - {{ urlpath "mynamedroute" "pathParameter_ifneeded" }}
// - {{ render "header.html" }}
// - {{ render_r "header.html" }} // partial relative path to current page
// - {{ yield }}
// - {{ current }}
app.AttachView(view.HTML("./templates", ".html"))
app.Get("/template", func(ctx context.Context) {
ctx.ViewData("Name", "Iris") // the .Name inside the ./templates/hi.html
ctx.Gzip(true) // enable gzip for big files
ctx.View("hi.html") // render the template with the file name relative to the './templates'
})
// http://localhost:8080/binary
// http://localhost:8080/text
// http://localhost:8080/json
// http://localhost:8080/jsonp
// http://localhost:8080/xml
// http://localhost:8080/markdown
// http://localhost:8080/template
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,74 +0,0 @@
package main
import (
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
)
var markdownContents = []byte(`## Hello Markdown
This is a sample of Markdown contents
Features
--------
All features of Sundown are supported, including:
* **Compatibility**. The Markdown v1.0.3 test suite passes with
the --tidy option. Without --tidy, the differences are
mostly in whitespace and entity escaping, where blackfriday is
more consistent and cleaner.
* **Common extensions**, including table support, fenced code
blocks, autolinks, strikethroughs, non-strict emphasis, etc.
* **Safety**. Blackfriday is paranoid when parsing, making it safe
to feed untrusted user input without fear of bad things
happening. The test suite stress tests this and there are no
known inputs that make it crash. If you find one, please let me
know and send me the input that does it.
NOTE: "safety" in this context means *runtime safety only*. In order to
protect yourself against JavaScript injection in untrusted content, see
[this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
* **Fast processing**. It is fast enough to render on-demand in
most web applications without having to cache the output.
* **Routine safety**. You can run multiple parsers in different
goroutines without ill effect. There is no dependence on global
shared state.
* **Minimal dependencies**. Blackfriday only depends on standard
library packages in Go. The source code is pretty
self-contained, so it is easy to add to any project, including
Google App Engine projects.
* **Standards compliant**. Output successfully validates using the
W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
[this is a link](https://github.com/kataras/iris) `)
// Cache should not be used on handlers that contain dynamic data.
// Cache is a good and a must-feature on static content, i.e "about page" or for a whole blog site.
func main() {
app := iris.New()
app.Get("/", iris.Cache(10*time.Second), writeMarkdown)
// saves its content on the first request and serves it instead of re-calculating the content.
// After 10 seconds it will be cleared and resetted.
app.Run(iris.Addr(":8080"))
}
func writeMarkdown(ctx context.Context) {
// tap multiple times the browser's refresh button and you will
// see this println only once every 10 seconds.
println("Handler executed. Content refreshed.")
ctx.Markdown(markdownContents)
}

View File

@@ -1,34 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/typescript" // optionally
"github.com/kataras/iris/typescript/editor"
)
func main() {
app := iris.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/"
ts.Attach(app) // attach the typescript compiler adaptor
editorConfig := editor.Config{
Hostname: "localhost",
Port: 4444,
WorkingDir: "./www/scripts/", // "/path/to/the/client/side/directory/",
Username: "myusername",
Password: "mypassword",
}
e := editor.New(editorConfig)
e.Attach(app) // attach the editor
app.StaticWeb("/", "./www") // serve the index.html
app.Run(iris.Addr(":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 (
stdContext "context"
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/host"
)
// Before continue, please read the below notes:
//
// Current version of Iris is auto-graceful on control+C/command+C
// or kill command sent or whenever app.Shutdown called.
//
// In order to add a custom interrupt handler(ctrl+c/cmd+c) or
// shutdown manually you have to "schedule a host supervisor's task" or
// use the core/host package manually or use a pure http.Server as we already seen at "custom-server" example.
//
// At this example, we will disable the interrupt handler and set our own interrupt handler.
func main() {
app := iris.New()
// output startup banner and error logs on os.Stdout
app.Get("/", func(ctx context.Context) {
ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>")
})
// tasks are always running in their go-routine by-default.
//
// register custom interrupt handler, fires when ctrl+C/cmd+C pressed or kill command sent.
app.Scheduler.Schedule(host.OnInterrupt(func(proc host.TaskProcess) {
println("Shutdown the server gracefully...")
timeout := 5 * time.Second // give the server 5 seconds to wait for idle connections.
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
defer cancel()
proc.Host().Shutdown(ctx) // Shutdown the underline supervisor's server
}))
// Start the server and disable the default interrupt handler in order to use our scheduled interrupt task.
app.Run(iris.Addr(":8080"), iris.WithoutInterruptHandler)
}
// Note:
// You can just use an http.Handler with your own signal notify channel and do that as you did with the net/http
// package. I will not show this way, but you can find many examples on the internet.

View File

@@ -1,72 +0,0 @@
package main
import (
stdContext "context"
"net/http"
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/host"
)
// The difference from its parent main.go is that
// with a custom host we're able to call the host's shutdown
// and be notified about its .Shutdown call.
// Almost the same as before.
func main() {
app := iris.New()
// output startup banner and error logs on os.Stdout
app.Get("/", func(ctx context.Context) {
ctx.HTML(" <h1>hi, I just exist in order to see if the server is closed</h1>")
})
// build the framework when all routing-relative actions are declared.
if err := app.Build(); err != nil {
panic(err)
}
// create our custom host supervisor by adapting
// a custom http server
srv := host.New(&http.Server{Addr: ":8080", Handler: app})
// tasks are always running in their go-routine by-default.
//
// register custom interrupt handler, fires when ctrl+C/cmd+C pressed or kill command sent, as we did before.
srv.Schedule(host.OnInterrupt(func(proc host.TaskProcess) {
println("Shutdown the server gracefully...")
timeout := 5 * time.Second // give the server 5 seconds to wait for idle connections.
ctx, cancel := stdContext.WithTimeout(stdContext.Background(), timeout)
defer cancel()
proc.Host().DeferFlow() // defer the exit, in order to catch the event
srv.Shutdown(ctx) // Shutdown the supervisor, only this way the proc.Host().Done will be notified
// the proc.Host().Shutdown, closes the underline server but no the supervisor.
// This behavior was choosen because is inneed for custom maintanance services
// (i.e restart server every week without loosing connections) which you can easly adapt with Iris.
}))
// schedule a task to be notify when the server was closed by our interrutp handler,
// optionally ofcourse.
srv.ScheduleFunc(func(proc host.TaskProcess) {
select {
case <-proc.Host().Done(): // when .Host.Shutdown(ctx) called.
println("Server was closed.")
proc.Host().RestoreFlow() // Restore the flow in order to exit(continue after the srv.ListenAndServe)
}
})
// Start our custom host
println("Server is running at :8080")
srv.ListenAndServe()
// Go to the console and press ctrl+c(for windows and linux) or cmd+c for osx.
// The output should be:
// Server is running at:8080
// Shutdown the server gracefully...
// Server was closed.
}
// Note:
// You can just use an http.Handler with your own signal notify channel and do that as you did with the net/http
// package. I will not show this way, but you can find many examples on the internet.

View File

@@ -1 +0,0 @@
hi = Γεια, %s

View File

@@ -1,71 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
"github.com/kataras/iris/sessions/sessiondb/redis"
"github.com/kataras/iris/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()
// Attach the session manager we just created
app.AttachSessionManager(mySessions)
app.Get("/", func(ctx context.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx context.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 context.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 context.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx context.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx context.Context) {
//destroy, removes the entire session data and cookie
ctx.SessionDestroy()
})
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,43 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
)
func main() {
app := iris.New()
// output startup banner and error logs on os.Stdout
sess := sessions.New(sessions.Config{Cookie: "myappsessionid"})
app.AttachSessionManager(sess)
app.Get("/set", func(ctx context.Context) {
ctx.Session().SetFlash("name", "iris")
ctx.Writef("Message setted, is available for the next request")
})
app.Get("/get", func(ctx context.Context) {
name := ctx.Session().GetFlashString("name")
if name == "" {
ctx.Writef("Empty name!!")
return
}
ctx.Writef("Hello %s", name)
})
app.Get("/test", func(ctx context.Context) {
name := ctx.Session().GetFlashString("name")
if name == "" {
ctx.Writef("Empty name!!")
return
}
ctx.Writef("Ok you are comming from /set ,the value of the name is %s", name)
ctx.Writef(", and again from the same context: %s", name)
})
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,56 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
)
var (
key = "my_sessionid"
)
func secret(ctx context.Context) {
// Check if user is authenticated
if auth, _ := ctx.Session().GetBoolean("authenticated"); !auth {
ctx.StatusCode(iris.StatusForbidden)
return
}
// Print secret message
ctx.WriteString("The cake is a lie!")
}
func login(ctx context.Context) {
session := ctx.Session()
// Authentication goes here
// ...
// Set user as authenticated
session.Set("authenticated", true)
}
func logout(ctx context.Context) {
session := ctx.Session()
// Revoke users authentication
session.Set("authenticated", false)
}
func main() {
app := iris.New()
// Look https://github.com/kataras/iris/tree/master/sessions/_examples for more features,
// i.e encode/decode and lifetime.
sess := sessions.New(sessions.Config{Cookie: key})
app.AttachSessionManager(sess)
app.Get("/secret", secret)
app.Get("/login", login)
app.Get("/logout", logout)
app.Run(iris.Addr(":8080"))
}

View File

@@ -1,28 +0,0 @@
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes), err
}
func CheckPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
func main() {
password := "secret"
hash, _ := HashPassword(password) // ignore error for the sake of simplicity
fmt.Println("Password:", password)
fmt.Println("Hash: ", hash)
match := CheckPasswordHash(password, hash)
fmt.Println("Match: ", match)
}

View File

@@ -1,78 +0,0 @@
package main
// developers can use any library to add a custom cookie encoder/decoder.
// At this example we use the gorilla's securecookie package:
// $ go get github.com/gorilla/securecookie
// $ go run main.go
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
"github.com/gorilla/securecookie"
)
func main() {
app := iris.New()
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,
})
// OPTIONALLY:
// import "github.com/kataras/iris/sessions/sessiondb/redis"
// or import "github.com/kataras/go-sessions/sessiondb/$any_available_community_database"
// mySessions.UseDatabase(redis.New(...))
app.AttachSessionManager(mySessions) // Attach the session manager we just created.
app.Get("/", func(ctx context.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx context.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 context.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 context.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx context.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx context.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.Run(iris.Addr(":8080"))
}

View File

@@ -1,120 +0,0 @@
package main
import (
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/sessions"
)
type businessModel struct {
Name string
}
func main() {
app := iris.New()
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,
// 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.
})
app.AttachSessionManager(mySessions) // Attach the session manager we just created.
app.Get("/", func(ctx context.Context) {
ctx.Writef("You should navigate to the /set, /get, /delete, /clear,/destroy instead")
})
app.Get("/set", func(ctx context.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"))
// Set will set the value as-it-is,
// if it's a slice or map
// you will be able to change it on .Get directly!
// Keep note that I don't recommend saving big data neither slices or maps on a session
// but if you really need it then use the `SetImmutable` instead of `Set`.
// Use `SetImmutable` consistently, it's slower.
// Read more about muttable and immutable go types: https://stackoverflow.com/a/8021081
})
app.Get("/get", func(ctx context.Context) {
// get a specific value, 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 context.Context) {
// delete a specific key
ctx.Session().Delete("name")
})
app.Get("/clear", func(ctx context.Context) {
// removes all entries
ctx.Session().Clear()
})
app.Get("/destroy", func(ctx context.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
// remember: slices and maps are muttable by-design
// The `SetImmutable` makes sure that they will be stored and received
// as immutable, so you can't change them directly by mistake.
//
// Use `SetImmutable` consistently, it's slower than `Set`.
// Read more about muttable and immutable go types: https://stackoverflow.com/a/8021081
app.Get("/set_immutable", func(ctx context.Context) {
business := []businessModel{{Name: "Edward"}, {Name: "value 2"}}
ctx.Session().SetImmutable("businessEdit", business)
businessGet := ctx.Session().Get("businessEdit").([]businessModel)
// try to change it, if we used `Set` instead of `SetImmutable` this
// change will affect the underline array of the session's value "businessEdit", but now it will not.
businessGet[0].Name = "Gabriel"
})
app.Get("/get_immutable", func(ctx context.Context) {
valSlice := ctx.Session().Get("businessEdit")
if valSlice == nil {
ctx.HTML("please navigate to the <a href='/set_immutable'>/set_immutable</a> first")
return
}
firstModel := valSlice.([]businessModel)[0]
// businessGet[0].Name is equal to Edward initially
if firstModel.Name != "Edward" {
panic("Report this as a bug, immutable data cannot be changed from the caller without re-SetImmutable")
}
ctx.Writef("[]businessModel[0].Name remains: %s", firstModel.Name)
// the name should remains "Edward"
})
app.Run(iris.Addr(":8080"))
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -1,33 +0,0 @@
package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/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()
ts := typescript.New()
ts.Config.Dir = "./www/scripts"
ts.Attach(app) // attach the application to the typescript compiler
app.StaticWeb("/", "./www") // serve the index.html
app.Run(iris.Addr(":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,114 +0,0 @@
package main
import (
"fmt"
"sync"
"time"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/view"
"github.com/kataras/iris/websocket"
)
type clientPage struct {
Title string
Host string
}
func main() {
app := iris.New()
app.AttachView(view.HTML("./templates", ".html")) // select the html engine to serve templates
ws := websocket.New(websocket.Config{
// the request path which the websocket client should listen/registered to the server,
// the endpoint is like a route.
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 context.Context) string {},
})
ws.Attach(app) // adapt the application to the websocket server
app.StaticWeb("/js", "./static/js") // serve our custom javascript code
app.Get("/", func(ctx context.Context) {
ctx.ViewData("", clientPage{"Client Page", "localhost:8080"})
ctx.View("client.html")
})
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.Run(iris.Addr(":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,175 +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 issue.
import (
"fmt"
"os"
"strings"
"time"
xwebsocket "golang.org/x/net/websocket"
"github.com/kataras/iris"
"github.com/kataras/iris/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:8080/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()
ws := websocket.New(websocket.Config{Endpoint: "/socket"})
ws.Attach(app)
ws.OnConnection(OnConnect)
app.Run(iris.Addr(":8080"))
}
// 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,63 +0,0 @@
package main
import (
"fmt"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/view"
"github.com/kataras/iris/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.AttachView(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,
})
ws.Attach(app) // 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 context.Context) {
ctx.ViewData("", clientPage{"Client Page", "localhost:8080"})
ctx.View("client.html")
})
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.Run(iris.Addr(":8080"))
}

Some files were not shown because too many files have changed in this diff Show More