打通网络

master
jager 3 years ago
parent 67d44ea967
commit afde513ad9

@ -0,0 +1,25 @@
plat ?= darwin
plats = linux darwin windows
arch ?= amd64
archs = amd64 arm arm64
all: server wechat
define build_app
@echo 'building $(1) ...'
@GOOS=$(2) GOARCH=$(3) go build -o builder/$(1) ./cmd/$(1)
@echo 'build $(1) done'
endef
server:
$(call build_app,server,$(plat),$(arch))
.PHONY: server
wechat:
$(call build_app,wechat,$(plat),$(arch))
.PHONY: wechat
clean:
@rm -f builder/*

Binary file not shown.

Binary file not shown.

@ -16,8 +16,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jageros/hawox/flags" "github.com/jageros/hawox/flags"
"github.com/jageros/hawox/httpx" "github.com/jageros/hawox/httpx"
"github.com/jageros/hawox/ws" "wechat/ws"
"gopkg.in/olahol/melody.v1"
) )
const appName = "wechat" const appName = "wechat"
@ -29,7 +28,4 @@ func main() {
r := engine.Group("ws") r := engine.Group("ws")
ws.Init(ctx, r, flags.Source()) ws.Init(ctx, r, flags.Source())
}) })
ws.OnMessage(func(session *melody.Session, bytes []byte) {
//ws.Broadcast()
})
} }

@ -13,20 +13,65 @@
package main package main
import ( import (
"encoding/json"
"flag"
"github.com/jageros/hawox/contextx"
"github.com/jageros/hawox/wsc"
"log" "log"
"net/http"
"os"
"wechat/types"
"wechat/view" "wechat/view"
) )
func main() { func main() {
//ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT) uid := flag.String("phone", "", "输入手机号码参数")
//defer cancel() flag.Parse()
if *uid == "" {
log.Fatal("请携带手机号码参数启动,--phone=10086")
os.Exit(-1)
}
ctx, cancel := contextx.Default()
defer cancel()
h := http.Header{}
h.Add("uid", *uid)
m := wsc.New(ctx)
sess, err := m.ConnectWithHeader("ws://127.0.0.1:8888/ws/wechat/1", h, map[string]interface{}{"uid": uid})
if err != nil {
panic(err)
}
view.OnSendMsg(func(msg string) {
err = sess.Write([]byte(msg))
if err != nil {
log.Println(err)
}
})
m.HandleMessageBinary(func(session *wsc.Session, bytes []byte) {
//uid, _ := session.Get("uid")
//roomId, _ := session.Get("roomId")
msg := &types.Msg{}
err := json.Unmarshal(bytes, msg)
if err != nil {
log.Panicf("msg.Unmarshal err: %v", err)
return
}
switch msg.MsgID {
case 1:
view.OnMessage(msg.Msg)
view.OnMessage("dekdmkwenkwndklwenklndk\n") case 2:
view.UpdateOnline("杰13160676597\n哲10086\n文10010\n") view.UpdateOnline(msg.Msg)
view.UpdateOnline("杰13160676597\n哲10086\n文10010\n")
default:
log.Printf("MsgId=%d Msg=%s", msg.MsgID, msg.Msg)
}
})
err := view.Run() err = view.Run()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

@ -4,8 +4,7 @@ go 1.17
require ( require (
github.com/gin-gonic/gin v1.7.4 github.com/gin-gonic/gin v1.7.4
github.com/jageros/hawox v0.0.5 github.com/jageros/hawox v0.0.6
github.com/jroimartin/gocui v0.5.0
github.com/rocket049/gocui v0.3.2 github.com/rocket049/gocui v0.3.2
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
) )
@ -14,7 +13,6 @@ require (
github.com/cespare/xxhash/v2 v2.1.1 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/eapache/queue v1.1.0 // indirect github.com/eapache/queue v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect
@ -40,7 +38,6 @@ require (
github.com/modern-go/reflect2 v1.0.1 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect github.com/nsf/termbox-go v1.1.1 // indirect
github.com/pelletier/go-toml v1.9.3 // indirect github.com/pelletier/go-toml v1.9.3 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.6.0 // indirect github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cast v1.3.1 // indirect

@ -99,7 +99,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
@ -283,12 +282,10 @@ github.com/iancoleman/strcase v0.1.2/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5N
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/jageros/hawox v0.0.5 h1:GJlcQ8G8r1T8roPLjm4Nb+cj/1Im2sVFL2Pmwlj072U= github.com/jageros/hawox v0.0.6 h1:4svDUSDrss47VYJ9rd1LyZBZJHSQtcj+C88wjjYPa8k=
github.com/jageros/hawox v0.0.5/go.mod h1:OFIFzzc5l6v52BgVIRLqmxQJnE+oEE6kOTvIqHOQF0o= github.com/jageros/hawox v0.0.6/go.mod h1:Z/+N+7E3dKGvtztI4TN2uIhP/cB/7zCecT+uv3ZgCLA=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jroimartin/gocui v0.5.0 h1:DCZc97zY9dMnHXJSJLLmx9VqiEnAj0yh0eTNpuEtG/4=
github.com/jroimartin/gocui v0.5.0/go.mod h1:l7Hz8DoYoL6NoYnlnaX6XCNR62G7J5FfSW5jEogzaxE=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -412,8 +409,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=

@ -13,17 +13,15 @@
package view package view
import ( import (
"fmt"
"github.com/rocket049/gocui" "github.com/rocket049/gocui"
"log" "log"
"time"
"wechat/ws"
) )
var ( var (
viewArr = []string{"msg", "send"} viewArr = []string{"msg", "send"}
active = 1 active = 1
gg *gocui.Gui gg *gocui.Gui
onSend func(msg string)
) )
func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) {
@ -81,6 +79,10 @@ func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit return gocui.ErrQuit
} }
func OnSendMsg(fn func(msg string)) {
onSend = fn
}
func OnMessage(msg string) { func OnMessage(msg string) {
gg.Update(func(gui *gocui.Gui) error { gg.Update(func(gui *gocui.Gui) error {
v, err := gui.View("msg") v, err := gui.View("msg")
@ -111,23 +113,13 @@ func sendMsg(g *gocui.Gui, v *gocui.View) error {
return v.SetCursor(0, 0) return v.SetCursor(0, 0)
} }
str := string(byts) str := string(byts)
msg, err := g.View("msg")
if err != nil {
return err
}
n, err := ws.SendMsg(str) if onSend != nil {
if err != nil { onSend(str)
return err
} }
msgStr := fmt.Sprintf("[%d]%s(%s): %s\n", n, "我", time.Now().Format("15:04:05"), str) v.Clear()
_, err = msg.Write([]byte(msgStr)) return v.SetCursor(0, 0)
if err == nil {
v.Clear()
err = v.SetCursor(0, 0)
}
return err
} }
func arrowUp(g *gocui.Gui, v *gocui.View) error { func arrowUp(g *gocui.Gui, v *gocui.View) error {
@ -161,6 +153,11 @@ func backspace(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
func clear(g *gocui.Gui, v *gocui.View) error {
v.Clear()
return v.SetCursor(0, 0)
}
func init() { func init() {
g, err := gocui.NewGui(gocui.OutputNormal) g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil { if err != nil {
@ -188,6 +185,10 @@ func init() {
log.Panic(err) log.Panic(err)
} }
if err := g.SetKeybinding("send", gocui.KeyCtrlD, gocui.ModNone, clear); err != nil {
log.Panic(err)
}
if err := g.SetKeybinding("send", gocui.KeyBackspace2, gocui.ModNone, backspace); err != nil { if err := g.SetKeybinding("send", gocui.KeyBackspace2, gocui.ModNone, backspace); err != nil {
log.Panic(err) log.Panic(err)
} }

@ -42,6 +42,8 @@ type service struct {
ctx contextx.Context ctx contextx.Context
m *melody.Melody m *melody.Melody
callTimeout time.Duration callTimeout time.Duration
online map[string]struct{}
mx sync.Mutex
} }
func Init(ctx contextx.Context, r *gin.RouterGroup, relativePath string) { func Init(ctx contextx.Context, r *gin.RouterGroup, relativePath string) {
@ -49,8 +51,9 @@ func Init(ctx contextx.Context, r *gin.RouterGroup, relativePath string) {
ctx: ctx, ctx: ctx,
m: melody.New(), m: melody.New(),
callTimeout: time.Second * 5, callTimeout: time.Second * 5,
online: map[string]struct{}{},
} }
ss.m.HandleMessageBinary(ss.handleMessage) ss.m.HandleMessage(ss.handleMessage)
ss.m.HandleConnect(ss.onConnect) ss.m.HandleConnect(ss.onConnect)
ss.m.HandleDisconnect(ss.onDisconnect) ss.m.HandleDisconnect(ss.onDisconnect)
r.GET(relativePath, ss.handler) r.GET(relativePath, ss.handler)
@ -59,7 +62,8 @@ func Init(ctx contextx.Context, r *gin.RouterGroup, relativePath string) {
func (s *service) handler(c *gin.Context) { func (s *service) handler(c *gin.Context) {
uid := c.GetHeader("uid") uid := c.GetHeader("uid")
if _, ok := names[uid]; !ok { if _, ok := names[uid]; !ok {
httpx.ErrInterrupt(c, errcode.InvalidParam) logx.Infof("=====uid=%s", uid)
httpx.ErrInterrupt(c, errcode.InvalidParam.WithMsg(uid))
return return
} }
err := s.m.HandleRequestWithKeys(c.Writer, c.Request, map[string]interface{}{"uid": uid}) err := s.m.HandleRequestWithKeys(c.Writer, c.Request, map[string]interface{}{"uid": uid})
@ -69,16 +73,54 @@ func (s *service) handler(c *gin.Context) {
} }
func (s *service) onConnect(session *melody.Session) { func (s *service) onConnect(session *melody.Session) {
uid, exist := session.Get("uid")
logx.Infof("on connect uid=%s", uid)
if !exist {
return
}
s.mx.Lock()
defer s.mx.Unlock()
s.online[uid.(string)] = struct{}{}
s.updateOnline()
} }
func (s *service) onDisconnect(session *melody.Session) { func (s *service) onDisconnect(session *melody.Session) {
uid, exist := session.Get("uid")
logx.Infof("on disconnect uid=%s", uid)
if !exist {
return
}
s.mx.Lock()
defer s.mx.Unlock()
delete(s.online, uid.(string))
s.updateOnline()
}
func (s *service) updateOnline() {
var msg string
for id := range s.online {
name := names[id]
msg = fmt.Sprintf("%s%s(%s)\n", msg, name, id)
}
var resp = &types.Msg{
MsgID: 2,
Msg: msg,
}
bty, err := json.Marshal(resp)
if err != nil {
return
}
err = s.m.BroadcastBinary(bty)
if err != nil {
logx.Error(err)
}
logx.Infof("update %s", msg)
} }
func (s *service) handleMessage(session *melody.Session, bytes []byte) { func (s *service) handleMessage(session *melody.Session, bytes []byte) {
start := time.Now() start := time.Now()
uid, exist := session.Get("uid") uid, exist := session.Get("uid")
logx.Infof("on msg uid=%s", uid)
if !exist { if !exist {
return return
} }
@ -99,7 +141,7 @@ func (s *service) handleMessage(session *melody.Session, bytes []byte) {
if err != nil { if err != nil {
return return
} }
err = s.m.Broadcast(bty) err = s.m.BroadcastBinary(bty)
if err != nil { if err != nil {
logx.Error(err) logx.Error(err)
} }
@ -107,4 +149,4 @@ func (s *service) handleMessage(session *melody.Session, bytes []byte) {
if take > time.Millisecond*100 { if take > time.Millisecond*100 {
logx.Warnf("send msg take: %s", take.String()) logx.Warnf("send msg take: %s", take.String())
} }
} }

@ -0,0 +1,14 @@
/**
* @Author: jager
* @Email: lhj168os@gmail.com
* @File: wsc
* @Date: 2021/10/21 2:47
* @package: wsc
* @Version: v1.0.0
*
* @Description:
*
*/
package wsc
Loading…
Cancel
Save