Share
Embed
Rest, Sockets & Golang
Uma introdução ao uso de Sockets usando Golang, apresenta as formas de criar seus próprios Sockets e qual cenário poderia está aplicando Sockets.
Aborda como a arquitetura Rest funciona e qual seria o cenário para sua aplicabilidade comparada com Socket.
A apresentação é uma tentativa de apresentar os recursos e poder do Golang quando o assunto é REST e Socket.
Jefferson Otoni Lima
December 26, 2017
Transcript
70 slides
-
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 1/70 REST, Sockets em
Golang Xml-RPC e WebSocket Je erson Otoni Lima CEO & Co-Fundador | S3wf & S3commerce entrepreneur 2007 Full-Stack programmer -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 3/70 Arquiteturas, protocolos para
troca de informações Web Services {http/https} / Rest (https://github.com/gorilla/mux) e Soap (https://github.com/ orix/wsdl2go) Sockets {tcp/udp} / pkg net (https://golang.org/pkg/net/) WebSocket {http/https} / pkg websocket (https://godoc.org/golang.org/x/net/websocket) Rpc {http/tcp} / pkg rpc (https://golang.org/pkg/net/rpc/) Codigos de exemplos Code/Golang (https://github.com/je otoni/gotalks) Apresentação sobre Socket Abrir aqui (http://go-talks.appspot.com/github.com/je otoni/gotalks/server-rest.slide) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 6/70 Socket / server
main() func main() { DeleteScock() // remove socket l, err := net.Listen("unix", SOCK) // var SOCK = "/tmp/unix.sock" if err != nil { log.Fatal("listen error:", err) } for { // Connection-oriented conn, err := l.Accept() // Opening connection defer l.Close() if err != nil { log.Fatal("accept error:", err) } go RedWriteSocket(conn) // Receive msg from server and send msg to server } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 8/70 Socket / server
func RedWriteSocket() func RedWriteSocket(conn net.Conn) { // Always Traveling and searching for messages for { buf := make([]byte, 512) // buffer nr, _ := conn.Read(buf) // Reading msg coming from server data := buf[0:nr] // data println("Server got:", string(data)) ///send client _, err = conn.Write([]byte("hello Client.. I'm the server, \n")) if err != nil { log.Fatal("Write: ", err) } } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 10/70 Socket / client
main() func main() { conn, err := net.Dial("unix", SOCK) // var SOCK = "/tmp/unix.sock" if err != nil { panic(err) } defer conn.Close() _, err = conn.Write([]byte("Hello, I'm the client.\n")) // Sending msg to the server readerServer(conn) // Receiving from server msg if err != nil { log.Fatal("write error:", err) } time.Sleep(1e9) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 12/70 Socket / client
readerServer() func readerServer(r io.Reader) { // Creating the buffer buf := make([]byte, 1024) // listen for { // Reading what comes from the server n, err := r.Read(buf[:]) if err != nil { return } println("Client got:", string(buf[0:n])) // Msg from server } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 14/70 O que é
Socket TCP ? net.Listen("tcp", PORT) net.ListenTCP("tcp", tcpAddr) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 16/70 Socket Tcp /
server main() func main() { tcp, err := net.Listen("tcp", PORT) // var PORT = :7777 or // ListenTCP("tcp", tcpAddr)) fmt.Println("Open port: ", PORT) checkError(err) conn, _ := tcp.Accept() defer conn.Close() // send new string back to client conn.Write([]byte("Welcome at the call client!" + "\n")) // will listen for message to process ending in newline (\n) message, _ := bufio.NewReader(conn).ReadString('\n') // output message received fmt.Print("Client sent: \n", string(message)) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 18/70 Socket Tcp /
client main() func main() { //Connect TCP conn, err := net.Dial("tcp", PORT) // var PORT = :7777 checkError(err) defer conn.Close() //simple Read buffer := make([]byte, 1024) n, _ := conn.Read(buffer) fmt.Println("server sent: ", string(buffer[0:n])) //simple write conn.Write([]byte("Hello, I'm the net client.\n")) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 20/70 O que é
WebSockets ? http.ListenAndServe(":1234", nil) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 22/70 WebSockets Server main
func main() { // Defining our api http.Handle("/chat", websocket.Handler(ListenWebSocker)) // Opening the door for receiving messages if err := http.ListenAndServe(":1234", nil); err != nil { log.Fatal("ListenAndServe:", err) } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 24/70 WebSockets ListenWebSocker() func
ListenWebSocker(ws *websocket.Conn) { for { // loop var reply string // Receive the message by reference // Receiving client message websocket.Message.Receive(ws, &reply) fmt.Println("Client sent: " + reply) msg := "Hello I'm the websocket server!" websocket.Message.Send(ws, msg) // Sending message to the client } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 26/70 WebSockets Client var
wsuri = "ws://127.0.0.1:1234/chat"; // Url window.onload = function() { sock = new WebSocket(wsuri); // Connecting in our websocket sock.onopen = function() { console.log("connected to " + wsuri); document.getElementById("connect").innerHTML = "online" } // Receiving message from the server sock.onmessage = function(e) { console.log("message received: " + e.data); document.getElementById('msg-server').value = e.data } }; function send() { // Sending msg to server var msg = document.getElementById('message').value; sock.send(msg); }; -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 29/70 Tipos de RCP
acrônimo de Remote Procedure Call (https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto) / GoRpc (https://github.com/valyala/gorpc) CORBA — padrão RPC independente de plataforma Sun RPC — RPC para as plataformas Unix e Linux DCOM — RPC para Windows RMI — RPC para Java SOAP — padrão RPC para web service JRES - Java Remote Execution -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 31/70 RPC http/https Server
func main() { // Recording the method Matt matt := new(Matt) rpc.Register(matt) // Recording the method Stop stop := new(Stop) rpc.Register(stop) // Start handler rpc.HandleHTTP() // Opening the port for communication err := http.ListenAndServe(":1234", nil) if err != nil { fmt.Println(err.Error()) } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 32/70 RPC http/https Call
Stop server type Stop string // My method StopServer func (s *Stop) StopServer(args *Args2, replys *string) error { *replys = args.A + " ok! " fmt.Println("Stopping the server by rpc!") var count = 5 for i := 0; i < count; i++ { fmt.Println("service[", i, "]", "stop") time.Sleep(2 * time.Second) } os.Exit(1) return nil } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 33/70 RPC http/https Client
func main() { // type Args2 struct { A string } // type Args struct { A, B int } // Synchronous call client, _ := rpc.DialHTTP("tcp", "localhost:1234") args := Args{335, 32} // Defining the arguments var reply int // Calling my method Muilt client.Call("Matt.Multiply", args, &reply) fmt.Printf("Matt: %d*%d=%d\n", args.A, args.B, reply) args2 := Args2{"Rpc client kill program!"} // Defining the arguments var stop string // Calling my method StopServer Of the type Stop client.Call("Stop.StopServer", args2, &stop) fmt.Printf("Stop: %s\n", args2.A) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 34/70 RPC Tcp /
Json Server func main() { arith := new(Arith) rpc.Register(arith) // Recording the method Stop stop := new(Stop) rpc.Register(stop) tcpAddr, err := net.ResolveTCPAddr("tcp", ":1234") checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() if err != nil { continue } //jsonrpc.ServeConn(conn) rpc.ServeConn(conn) } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 35/70 RPC Tcp /
Json Client func main() { //client, _ := jsonrpc.Dial("tcp", ":1234") client, _ := rpc.Dial("tcp", ":1234") // Synchronous call args := Args{335, 32} var reply int // Calling my method err := client.Call("Arith.Multiply", args, &reply) checkError(err) fmt.Printf("Arith: %d*%d=%d\n", args.A, args.B, reply) args2 := Args2{"Rpc client kill program!"} // Defining the arguments var stop string // Calling my method StopServer Of the type Stop err = client.Call("Stop.StopServer", args2, &stop) checkError(err) fmt.Printf("Stop: %s\n", args2.A) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 36/70 Tipos de Web
Services / http/https {json/xml} REST (https://pt.wikipedia.org/wiki/REST) / Framework Mux (https://github.com/gorilla/mux) SOAP (https://pt.wikipedia.org/wiki/SOAP) / framework {wsdl2Go (https://github.com/ orix/wsdl2go) , Soaptrip} (https://github.com/kylewolfe/soaptrip) XML-RPC (https://pt.wikipedia.org/wiki/XML-RPC) / XmlRpc (https://github.com/kolo/xmlrpc) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 38/70 Como funciona o
protocolo HTTP ? Hypertext Transfer Protocol (https://pt.wikipedia.org/wiki/Hypertext_Transfer_Protocol) Mensagem HTTP códigos http (https://pt.wikipedia.org/wiki/Lista_de_c%C3%B3digos_de_estado_HTTP) Cabeçalho da mensagem RFC 2616 (https://tools.ietf.org/html/rfc2616) Corpo da mensagem Requisição (Request-Line,Request-header,Method, URI e HTTP-Version) Métodos (GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS e CONNECT) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 40/70 O que é
REST ? REST (https://pt.wikipedia.org/wiki/REST) (Representational State Transfer) É uma abstração da arquitetura da World Wide Web [pattern] 2000 por Roy Fielding (https://en.wikipedia.org/wiki/Roy_Fielding) RPC (https://pt.wikipedia.org/wiki/Chamada_de_procedimento_remoto) não é um exemplo de REST RESTful (São as aplicações ou sistemas que usam princípio REST) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 42/70 Concepções Rest Resources
= /insert, /update , /search [URI] Representation = Html, Json, Xml, ... / Content-Type State Transfer = GET, POST, PUT ... -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 47/70 Clientes REST cURL
(criar requisições em diversos protocolos) (https://ec.haxx.se) Postman (https://www.getpostman.com/) HTTPie (https://httpie.org/) Hurl.it (https://www.hurl.it/) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 49/70 API Layers &
Serviços REST Api Gateway (https://console.aws.amazon.com/apigateway) (Amazon) Azure (https://docs.microsoft.com/en-us/azure/api-management/) (Microsoft) Dreamfactory (https://www.dreamfactory.com/) (Dreamfactory) Firebase (https:// rebase.google.com/docs/database/rest/start?hl=pt-br) (Google) kong (https://getkong.org/) (Gerenciador de APIs e Microserviços open - source) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 51/70 Frameworks REST github.com/sogko/slumber
(https://github.com/sogko/slumber) [Slumer]] awesome-go (https://github.com/avelino/awesome-go/blob/master/README.md) (links diversos) Mux (https://github.com/gorilla/mux) (simples roteador url) HttpRouter (https://github.com/julienschmidt/httprouter) (poderoso roteador url) Frisby (https://github.com/verdverm/frisby) (REST API TEST) Pressly chi (https://github.com/pressly/chi) (Http Service REST) Go JSON handler (https://github.com/rs/formjson) gores (https://github.com/alioygur/gores) (handles HTML, JSON, XML) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 54/70 Construindo nosso server
REST / ListenAndServe ( ) // http // http.ListenAndServe(":9999", nil) // servindo um site estático // http.ListenAndServe(":9999", http.FileServer(http.Dir("/static/site")))) // ssl // http.ListenAndServeTLS(":443", server.crt, yourkey.key, nil) // Criando chaves ssl // ~/user-linux$ openssl req -nodes -newkey rsa:2048 -keyout yourkey.key -out serve.csr -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 56/70 Server httpRouter {Criando
rotas} func main() { router := httprouter.New() router.GET("/", Index) // curl -X GET localhost:9999 router.GET("/user/:uid", getuser) // curl -X GET localhost:9999/user/23322 router.POST("/adduser/:uid", adduser) // curl -X POST localhost:9999/adduser/232 router.DELETE("/deluser/:uid", deleteuser) // curl -X DELETE localhost:9999/deluser/232 router.PUT("/moduser/:uid", modifyuser) // curl -X PUT localhost:9999/moduser/232 // abrindo porta log.Fatal(http.ListenAndServe(":9999", router)) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 57/70 Tipos de Uploads
func main() { router := mux.NewRouter() router. // multipart/form-data [email protected] HandleFunc("/upload-form", uploadFormFile).Methods("POST") router. // multipart/form-data =namefile[][email protected] HandleFunc("/upload-form-multi", uploadFormMuilt).Methods("POST") router. // --data-binary "@file1.jpg" HandleFunc("/upload-bin", uploadBinary) // listenAndServer(router) } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 58/70 Copy para servidor
único arquivio func uploadFormFile(w http.ResponseWriter, r *http.Request) { //sizeUpload := r.ContentLength / 1048576 // 1Mb convert to Mb file, handler, _ := r.FormFile("fileupload") r.ParseMultipartForm(10485760) defer file.Close() pathUserAcess := PathLocal + "/" + acessekey + "/" + handler.Filename existPath, _ := os.Stat(PathLocal + "/" + acessekey) if existPath == nil { os.MkdirAll(PathLocal+"/"+acessekey, 0777) } f, _ := os.OpenFile(pathUserAcess, os.O_WRONLY|os.O_CREATE, 0777) defer f.Close() fmt.Println("Copy: ", pathUserAcess) sizef, _ := io.Copy(f, file) fmt.Fprintln(w, "", 500, `{"msg":"ok upload size recebido"}`, sizef, "Bytes") } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 59/70 Copy para servidor
multipolos arquivos func uploadFormFileMulti(w http.ResponseWriter, r *http.Request, files []*multipart.FileHeader) { if len(r.MultipartForm.File["fileupload[]"]) > 0 { fmt.Println("size array: ", len(files)) var uploadSize int64 for i, _ := range files { file, err := files[i].Open() defer file.Close() pathUserAcess := PathLocal + "/" + acessekey + "/" + files[i].Filename existPath, _ := os.Stat(PathLocal + "/" + acessekey) if existPath == nil { os.MkdirAll(PathLocal+"/"+acessekey, 0777) } f, _ := os.Create(pathUserAcess) defer f.Close() fmt.Println("Copy: ", pathUserAcess) sizef, _ := io.Copy(f, file) if err == nil { uploadSize += sizef } } } } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 60/70 Uploads Binary func
uploadBinary(w http.ResponseWriter, r *http.Request) { pathUpKeyUser := PathLocal + "/" + acessekey nameFileUp := r.Header.Get("Name-File") pathUpKeyUserFull := pathUpKeyUser + "/" + nameFileUp existPath, _ := os.Stat(pathUpKeyUserFull) if existPath == nil { os.MkdirAll(pathUpKeyUser, 0777) } ff, _ := os.OpenFile(pathUpKeyUserFull, os.O_WRONLY|os.O_CREATE, 0777) defer ff.Close() fmt.Println("Copy: ", pathUpKeyUserFull) sizef, _ := io.Copy(ff, r.Body) fmt.Fprintln(w, "", 500, `{"msg":"ok upload size recebido"}`, sizef, "Bytes") } -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 63/70 Upload Form /
multipart/form-data curl -i -X POST http://localhost:9999/upload-form \ -u "API_KEY:383883jef903xxxx838xxxx" \ --form "fileupload=@files/file2.pdf" -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 64/70 Upload Form multi
/ multipart/form-data curl -i --request POST localhost:9999/upload-form-multi \ -u "API_KEY:383883jef903xxxx838xxxx" \ --form 'email=jefferson&password=3838373773' \ --form "fileupload[]=@files/file1.jpg" \ --form "fileupload[]=@files/file2.pdf" -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 65/70 Upload Binary //
http://https://xxxxxx.execute-api.us-xxx-x.amazonaws.com/upload-bin \ curl -i --request POST http://localhost:9999/upload-bin \ -u "API_KEY:383883jef903xxxx838xxxx" \ -H "Accept: binary/octet-stream" \ -H "Content-Type: binary/octet-stream" \ -H "Name-File: file2.pdf" \ --data-binary "@files/file2.pdf" -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 66/70 Referências github.com/avelino/awesome-go/blob/master/README.md (https://github.com/avelino/awesome-
go/blob/master/README.md) golang.org/pkg/net (https://golang.org/pkg/net) godoc.org/golang.org/x/net/websocket (https://godoc.org/golang.org/x/net/websocket) golang.org/pkg/net/rpc (https://golang.org/pkg/net/rpc) github.com/gorilla/mux (https://github.com/gorilla/mux) github.com/ orix/wsdl2go (https://github.com/ orix/wsdl2go) github.com/julienschmidt/httprouter (https://github.com/julienschmidt/httprouter) -
29/08/2018 REST, Sockets em Golang https://go-talks.appspot.com/github.com/jeffotoni/gotalks/server-rest.slide#1 69/70 Thank you Je
erson Otoni Lima CEO & Co-Fundador | S3wf & S3commerce entrepreneur 2007 Full-Stack programmer