-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(udp): Added udp server * feat(udp): Added udp server * feat(udp): Added udp server * feat(udp): Added udp server * feat(udp): Added udp server * feat(udp): Added udp server
- Loading branch information
Showing
6 changed files
with
201 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,4 +15,4 @@ | |
vendor/ | ||
.idea | ||
_backup | ||
_example | ||
example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# UDP | ||
|
||
## Server | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"log" | ||
"net" | ||
|
||
"github.com/go-kratos/kratos/v2" | ||
|
||
"github.com/go-packagist/go-kratos-components/udp" | ||
) | ||
|
||
func main() { | ||
err := kratos.New( | ||
kratos.Server( | ||
udp.NewServer(":12190", udp.WithHandler(func(conn net.PacketConn, buf []byte, addr net.Addr) { | ||
log.Println(string(buf)) | ||
}), udp.WithRecoveryHandler(func(conn net.PacketConn, buf []byte, addr net.Addr, err interface{}) { | ||
log.Println(err) | ||
})), | ||
), | ||
).Run() | ||
|
||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package udp | ||
|
||
import ( | ||
"context" | ||
"log" | ||
"net" | ||
) | ||
|
||
type Server struct { | ||
address string | ||
|
||
bufSize int | ||
|
||
conn net.PacketConn | ||
|
||
handler func(conn net.PacketConn, buf []byte, addr net.Addr) | ||
|
||
recoveryHandler func(conn net.PacketConn, buf []byte, addr net.Addr, err interface{}) | ||
} | ||
|
||
type Option func(*Server) | ||
|
||
func WithBufSize(bufSize int) Option { | ||
return func(s *Server) { | ||
if bufSize > 0 { | ||
s.bufSize = bufSize | ||
} | ||
} | ||
} | ||
|
||
func WithHandler(handler func(conn net.PacketConn, buf []byte, addr net.Addr)) Option { | ||
return func(s *Server) { | ||
if handler != nil { | ||
s.handler = handler | ||
} | ||
} | ||
} | ||
|
||
func WithRecoveryHandler(handler func(conn net.PacketConn, buf []byte, addr net.Addr, err interface{})) Option { | ||
return func(s *Server) { | ||
if handler != nil { | ||
s.recoveryHandler = handler | ||
} | ||
} | ||
} | ||
|
||
func NewServer(address string, opts ...Option) *Server { | ||
s := &Server{ | ||
address: address, | ||
bufSize: 1024, | ||
} | ||
|
||
for _, opt := range opts { | ||
opt(s) | ||
} | ||
|
||
return s | ||
} | ||
|
||
func (s *Server) Start(ctx context.Context) (err error) { | ||
s.conn, err = net.ListenPacket("udp", s.address) | ||
if err != nil { | ||
return | ||
} | ||
|
||
log.Printf("udp server: listening on %s\n", s.address) | ||
|
||
buf := make([]byte, s.bufSize) | ||
|
||
for { | ||
n, addr, err := s.conn.ReadFrom(buf) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if s.handler == nil { | ||
log.Printf("udp server: receive from %s: %s\n", addr.String(), string(buf)) | ||
continue | ||
} | ||
|
||
go s.handle(buf[:n], addr) | ||
} | ||
|
||
} | ||
|
||
func (s *Server) handle(buf []byte, addr net.Addr) { | ||
if s.recoveryHandler != nil { | ||
defer func() { | ||
if err := recover(); err != nil { | ||
s.recoveryHandler(s.conn, buf, addr, err) | ||
} | ||
}() | ||
} | ||
|
||
s.handler(s.conn, buf, addr) | ||
} | ||
|
||
func (s *Server) Stop(ctx context.Context) error { | ||
log.Println("udp server: stopping") | ||
|
||
return s.conn.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package udp | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"sync" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestServer(t *testing.T) { | ||
var ( | ||
server *Server | ||
wg sync.WaitGroup | ||
done = make(chan []byte, 1) | ||
) | ||
|
||
wg.Add(2) | ||
|
||
go func() { | ||
defer wg.Done() | ||
|
||
server = NewServer(":12190", WithHandler(func(conn net.PacketConn, buf []byte, addr net.Addr) { | ||
done <- buf | ||
}), WithRecoveryHandler(func(conn net.PacketConn, buf []byte, addr net.Addr, err interface{}) { | ||
t.Log(err) | ||
}), WithBufSize(1024)) | ||
|
||
go server.Start(context.Background()) | ||
|
||
time.Sleep(time.Second * 5) | ||
server.Stop(context.Background()) | ||
}() | ||
|
||
go func() { | ||
defer wg.Done() | ||
|
||
time.Sleep(time.Second * 3) | ||
|
||
c, err := net.Dial("udp", ":12190") | ||
if err != nil { | ||
t.Error(err) | ||
return | ||
} | ||
defer c.Close() | ||
|
||
_, err = c.Write([]byte("test")) | ||
if err != nil { | ||
t.Error(err) | ||
return | ||
} | ||
}() | ||
|
||
wg.Wait() | ||
|
||
buf := <-done | ||
if string(buf) != "test" { | ||
t.Fatal("buf not equal test") | ||
} | ||
} |