• 创建服务器
    • 创建 http 服务器
    • 创建 fasthttp 服务器
    • 创建 TCP 服务器
    • 创建 Unix Socket 服务器
    • 创建 WebSocket 服务器
    • 跟 gin 框架结合
    • 跟 echo 框架结合
    • 跟 beego 框架结合
    • 跟 iris 框架结合
    • Socket 服务器的启动与关闭
      • Start 和 Handle 方法区别
      • Stop 和 Close 方法的区别
      • Restart 方法

    创建服务器

    创建 http 服务器

    1. package main
    2.  
    3. import (
    4. "net/http"
    5.  
    6. "github.com/hprose/hprose-golang/rpc"
    7. )
    8.  
    9. func hello(name string) string {
    10. return "Hello " + name + "!"
    11. }
    12.  
    13. func main() {
    14. service := rpc.NewHTTPService()
    15. service.AddFunction("hello", hello)
    16. http.ListenAndServe(":8080", service)
    17. }

    创建 fasthttp 服务器

    1. package main
    2.  
    3. import (
    4. rpc "github.com/hprose/hprose-golang/rpc/fasthttp"
    5. "github.com/valyala/fasthttp"
    6. )
    7.  
    8. func hello(name string) string {
    9. return "Hello " + name + "!"
    10. }
    11.  
    12. func main() {
    13. service := rpc.NewFastHTTPService()
    14. service.AddFunction("hello", hello)
    15. fasthttp.ListenAndServe(":8080", service.ServeFastHTTP)
    16. }

    对比上面两个服务,我们发现服务函数(方法)的编写和发布上是没有区别的,区别只在于创建服务器所使用的构造函数和启动服务器所使用的库。

    上面的例子发布的是单个的函数,实际上不仅仅可以发布单个的函数,还可以同时发布多个函数,多个方法,多个结构体对象等等,后面我们会详细介绍这些。这里以发布 hello 函数为例,目的是为了突出创建服务器这个重点。

    注意 import 的路径是有所不同的。

    创建 TCP 服务器

    1. package main
    2.  
    3. import (
    4. "github.com/hprose/hprose-golang/rpc"
    5. )
    6.  
    7. func hello(name string) string {
    8. return "Hello " + name + "!"
    9. }
    10.  
    11. func main() {
    12. server := rpc.NewTCPServer("tcp4://0.0.0.0:4321/")
    13. server.AddFunction("hello", hello)
    14. server.Start()
    15. }

    同样服务编写和发布没有区别,区别只在于构造函数和服务的启动。在这里我们创建 TCP 服务器时,使用的是 TCPServer 而不是 TCPService,这可以省去自己创建监听 TCP 服务器的麻烦,但是如果你愿意自己来做这部分也可以,使用 TCPService 就可以了。例如:

    1. service := rpc.NewTCPService()
    2. service.AddFunction("hello", hello)
    3. addr, _ := net.ResolveTCPAddr("tcp", ":4321")
    4. listener, _ := net.ListenTCP("tcp", addr)
    5. service.ServeTCP(listener)

    当然上面这个使用 service 发布服务的代码只是一个最简单的例子,它并不完备,如果你要自己实现一个完备的 TCP 服务器,还需要做好多工作,上面的代码只是为了说明 servicelistener 如何结合。

    创建 Unix Socket 服务器

    1. package main
    2.  
    3. import (
    4. "github.com/hprose/hprose-golang/rpc"
    5. )
    6.  
    7. func hello(name string) string {
    8. return "Hello " + name + "!"
    9. }
    10.  
    11. func main() {
    12. server := rpc.NewUnixServer("unix:/tmp/my.sock")
    13. server.AddFunction("hello", hello)
    14. server.Start()
    15. }

    这个跟 TCP 服务很类似,不多作介绍了。关于 UnixService 的用法同上面的 TCPService 也是类似的,也略过不做介绍了。

    创建 WebSocket 服务器

    1. package main
    2.  
    3. import (
    4. "net/http"
    5.  
    6. rpc "github.com/hprose/hprose-golang/rpc/websocket"
    7. )
    8.  
    9. func hello(name string) string {
    10. return "Hello " + name + "!"
    11. }
    12.  
    13. func main() {
    14. service := rpc.NewWebSocketService()
    15. service.AddFunction("hello", hello)
    16. http.ListenAndServe(":8080", service)
    17. }

    这个跟 HTTP 服务器的创建很类似,而且这个 WebSocket 的 hprose 服务器,同时也是一个 HTTP 的 hprose 服务器,它可以同时接受 HTTP 和 WebSocket 的 hprose 客户端请求。

    注意 import 的路径是有所不同的。

    跟 gin 框架结合

    HTTP\HTTPS 和 WebSocket 服务并没有单独实现 Server,而只是实现了 Service,所以,这些服务器的启动与关闭依赖于你所使用的 http 库或框架。上面在创建服务器一节中,我们已经介绍了使用 net/http 和 fasthttp 如何来创建服务器。下面我们再举一个在 gin 框架下面如何发布服务的例子:

    1. package main
    2.  
    3. import (
    4. "github.com/hprose/hprose-golang/rpc"
    5. "gopkg.in/gin-gonic/gin.v1"
    6. )
    7.  
    8. func hello(name string) string {
    9. return "Hello " + name + "!"
    10. }
    11.  
    12. func main() {
    13. service := rpc.NewHTTPService()
    14. service.AddFunction("hello", hello)
    15. router := gin.Default()
    16. router.Any("/path", func(c *gin.Context) {
    17. service.ServeHTTP(c.Writer, c.Request)
    18. })
    19. router.Run(":8080")
    20. }

    上面代码中的 "/path" 可以是任意你希望发布 hprose 服务的路径,一个入口,所有的 Hprose 服务都从这里开始。

    WebSocket 服务器跟上面的写法类似,只要把 rpc.NewHTTPService() 换成 rpc.NewWebSocketService() 就可以了,另外注意修改一下导入包的路径。

    跟 echo 框架结合

    1. package main
    2.  
    3. import (
    4. "github.com/hprose/hprose-golang/rpc"
    5. "github.com/labstack/echo"
    6. )
    7.  
    8. func hello(name string) string {
    9. return "Hello " + name + "!"
    10. }
    11.  
    12. func main() {
    13. service := rpc.NewHTTPService()
    14. service.AddFunction("hello", hello)
    15. e := echo.New()
    16. e.Any("/path", echo.WrapHandler(service))
    17. e.Start(":8080")
    18. }

    上面代码中的 "/path" 可以是任意你希望发布 hprose 服务的路径,一个入口,所有的 Hprose 服务都从这里开始。

    WebSocket 服务器跟上面的写法类似,只要把 rpc.NewHTTPService() 换成 rpc.NewWebSocketService() 就可以了。另外注意修改一下导入包的路径。

    跟 beego 框架结合

    1. package main
    2.  
    3. import (
    4. "github.com/astaxie/beego"
    5. "github.com/hprose/hprose-golang/rpc"
    6. )
    7.  
    8. func hello(name string) string {
    9. return "Hello " + name + "!"
    10. }
    11.  
    12. func main() {
    13. service := rpc.NewHTTPService()
    14. service.AddFunction("hello", hello)
    15. beego.Handler("/path", service)
    16. beego.Run()
    17. }

    发布 WebSocket 服务的方式,跟 gin 和 echo 一样。

    跟 iris 框架结合

    1. package main
    2.  
    3. import (
    4. rpc "github.com/hprose/hprose-golang/rpc/fasthttp"
    5. "github.com/kataras/iris"
    6. )
    7.  
    8. func hello(name string) string {
    9. return "Hello " + name + "!"
    10. }
    11.  
    12. func main() {
    13. service := rpc.NewFastHTTPService()
    14. service.AddFunction("hello", hello)
    15. iris.Any("/path", func(c *iris.Context) {
    16. service.ServeFastHTTP(c.RequestCtx)
    17. })
    18. iris.Listen(":8080")
    19. }

    跟 gin 和 echo 不同,iris 是基于 fasthttp 的,所以这里创建的是 FastHTTPService。注意导入包的路径。

    Socket 服务器的启动与关闭

    下面来介绍一下关于 TCPServerUnixServer 的启动与关闭。

    Start 和 Handle 方法区别

    TCPServerUnixServer 都包含 StartHandle 两个方法,它俩的功能很接近,都是用于启动服务。区别是:

    Handle 启动服务是非阻塞的,Handle 启动服务后,代码会继续执行。

    Start 启动服务之后会阻塞不再向下执行。Start 启动之后,会监听以下的系统信号:

    • syscall.SIGHUP
    • syscall.SIGQUIT
    • syscall.SIGTERM
    • syscall.SIGINT
    • syscall.SIGKILL
      当收到 syscall.SIGHUP 信号时,服务会重启。当收到其它几个信号时,服务会关闭。

    Stop 和 Close 方法的区别

    Stop 对应 Start 方法,Close 对应 Handle 方法。即,Stop 方法实际上是发送一个 syscall.SIGQUIT 信号给 Start 启动的服务器以结束服务,对于直接使用 Handle 方法启动的服务,Stop 方法无效。使用 Close 方法可以关闭使用 Handle 方法启动的服务。

    Restart 方法

    Restart 这个也是用于重启使用 Start 方法启动的服务的,对于直接使用 Handle 方法启动的服务无效。