Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
fanux committed Dec 29, 2015
0 parents commit 2b04e0c
Show file tree
Hide file tree
Showing 12 changed files with 2,557 additions and 0 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#lhttp
###discribe
lhttp is a http like protocol but using websocket provide long live
###protocol
```go
Command\r\n --------start line,define command
Header1:value\r\n --------headers
Header2:value\r\n
\r\n
body --------message body
```
for example:
```go
chat\r\n
content-type:json\r\n
to:jack\r\n
from:mike\r\n
\r\n
{
message:hello jack,
time:1990-1210 5:30:48
}
```
###usage
1. define your processor,you need combine ```BaseProcessor```
```go
type ChatProcessor struct {
BaseProcessor
}
```
2. regist your processor
```go
Regist('chat',&ChatProcessor{})
```
then if command is 'chat' ChatProcessor will handle it
3.define your onmessage handle
```go
func (p *ChatProcessor)onMessage(h *WsHandler) {
h.Send(h.GETbody())
}
```
109 changes: 109 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package lhttp

import (
"bufio"
"crypto/tls"
"io"
"net"
"net/http"
"net/url"
)

// DialError is an error that occurs while dialling a websocket server.
type DialError struct {
*Config
Err error
}

func (e *DialError) Error() string {
return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error()
}

// NewConfig creates a new WebSocket config for client connection.
func NewConfig(server, origin string) (config *Config, err error) {
config = new(Config)
config.Version = ProtocolVersionHybi13
config.Location, err = url.ParseRequestURI(server)
if err != nil {
return
}
config.Origin, err = url.ParseRequestURI(origin)
if err != nil {
return
}
config.Header = http.Header(make(map[string][]string))
return
}

// NewClient creates a new WebSocket client connection over rwc.
func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {
br := bufio.NewReader(rwc)
bw := bufio.NewWriter(rwc)
err = hybiClientHandshake(config, br, bw)
if err != nil {
return
}
buf := bufio.NewReadWriter(br, bw)
ws = newHybiClientConn(config, buf, rwc)
return
}

// Dial opens a new client connection to a WebSocket.
func Dial(url_, protocol, origin string) (ws *Conn, err error) {
config, err := NewConfig(url_, origin)
if err != nil {
return nil, err
}
if protocol != "" {
config.Protocol = []string{protocol}
}
return DialConfig(config)
}

var portMap = map[string]string{
"ws": "80",
"wss": "443",
}

func parseAuthority(location *url.URL) string {
if _, ok := portMap[location.Scheme]; ok {
if _, _, err := net.SplitHostPort(location.Host); err != nil {
return net.JoinHostPort(location.Host, portMap[location.Scheme])
}
}
return location.Host
}

// DialConfig opens a new client connection to a WebSocket with a config.
func DialConfig(config *Config) (ws *Conn, err error) {
var client net.Conn
if config.Location == nil {
return nil, &DialError{config, ErrBadWebSocketLocation}
}
if config.Origin == nil {
return nil, &DialError{config, ErrBadWebSocketOrigin}
}
switch config.Location.Scheme {
case "ws":
client, err = net.Dial("tcp", parseAuthority(config.Location))

case "wss":
client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig)

default:
err = ErrBadScheme
}
if err != nil {
goto Error
}

ws, err = NewClient(config, client)
if err != nil {
client.Close()
goto Error
}
return

Error:
return nil, &DialError{config, err}
}
27 changes: 27 additions & 0 deletions exampledial_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package lhttp

import (
"fmt"
"log"

"golang.org/x/net/websocket"
)

// This example demonstrates a trivial client.
func ExampleDial() {
origin := "http://localhost/"
url := "ws://localhost:12345/ws"
ws, err := websocket.Dial(url, "", origin)
if err != nil {
log.Fatal(err)
}
if _, err := ws.Write([]byte("hello, world!\n")); err != nil {
log.Fatal(err)
}
var msg = make([]byte, 512)
var n int
if n, err = ws.Read(msg); err != nil {
log.Fatal(err)
}
fmt.Printf("Received: %s.\n", msg[:n])
}
22 changes: 22 additions & 0 deletions examplehandler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package lhttp

import (
"io"
"net/http"

"golang.org/x/net/websocket"
)

// Echo the data received on the WebSocket.
func EchoServer(ws *websocket.Conn) {
io.Copy(ws, ws)
}

// This example demonstrates a trivial echo server.
func ExampleHandler() {
http.Handle("/echo", websocket.Handler(EchoServer))
err := http.ListenAndServe(":12345", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
13 changes: 13 additions & 0 deletions handlerHub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package lhttp

type HandlerHub struct {
}

func (h *HandlerHub) Get(connSetID string) *WsHandler {
//TODO
return &WsHandler{}
}
func (h *HandlerHub) Add(connSetID string, w *WsHandler) {
}
func (h *HandlerHub) Delete(w *WsHandler) {
}
Loading

0 comments on commit 2b04e0c

Please sign in to comment.