workflows web
- servidor Works Web pode ser resumido simplesmente como
- Cliente estabelece para o servidor através da conexão protocolo TCP TCP / IP
- O cliente envia para o servidor HTTP pacote de solicitação de protocolo, os recursos do servidor que pedem no documento
- O servidor envia para o pacote de resposta protocolo HTTP cliente, se o recurso solicitado contém conteúdo linguagem dinâmica, o servidor chama as alças motor de interpretação de "conteúdo dinâmico" linguagens dinâmicas e processar a volta dados resultantes para o cliente
- Cliente e servidor está desligado. Pelo cliente interpreta o documento HTML, o resultado de renderização de gráficos na tela do cliente
protocolo HTTP
- Hypertext Transfer Protocol (HTTP, Hypertext Transfer Protocol) é o protocolo de rede mais amplamente utilizado da Internet, que detalha as regras de comunicação mútua entre o navegador eo servidor Web, o protocolo de transferência de documentos da World Wide Web para transferir dados através da Internet
- protocolo HTTP através do protocolo TCP normalmente realizado
http servidor
package main
import (
"fmt"
"net/http"
)
// /go handler
func goHandler(w http.ResponseWriter, r *http.Request) {
// 获取远程地址
fmt.Println(r.RemoteAddr, "连接成功")
// 获取请求类型
fmt.Println("请求方法: ", r.Method)
// 获取url路径
fmt.Println("url path: ", r.URL.Path)
// 获取header数据
fmt.Println("header: ", r.Header)
// 获取请求body内容
fmt.Println("body: ", r.Body)
// 返回信息
_, _ = w.Write([]byte("hello world"))
}
func main() {
// 单独写回掉函数
http.HandleFunc("/go", goHandler)
// 启动http监听
_ = http.ListenAndServe("127.0.0.1:8000", nil)
}
http pacote do cliente
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, err := http.Get("http://127.0.0.1:8000/go")
if err != nil {
fmt.Println("获取数据失败, err: ", err)
return
}
defer resp.Body.Close()
// 获取http状态码
fmt.Println("status: ", resp.Status)
// 获取header信息
fmt.Println("header: ", resp.Status)
buf := make([]byte, 124)
for {
// 接收服务端数据
n, err := resp.Body.Read(buf)
fmt.Println(string(buf[:n]))
if err == io.EOF {
break
}
if err != nil {
fmt.Println("数据读取失败, err: ", err)
continue
}
}
}
implementos de pacotes TCP do cliente
package main
import (
"fmt"
"io"
"net"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8000")
if err != nil {
fmt.Println("connect err: ", err)
return
}
defer conn.Close()
msg := "GET /go HTTP/1.1\r\n"
msg += "Host: 127.0.0.1:8000\r\n"
msg += "Connection: close\r\n"
msg += "\r\n\r\n"
_, err = io.WriteString(conn, msg)
if err != nil {
fmt.Println("write string failed, ", err)
return
}
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if err == io.EOF {
break
}
if err != nil {
fmt.Println("recv data has err, ", err)
break
}
fmt.Println(string(buf[:n]))
}
}
outro erro
golang GET 出现 x509: certificado assinado por uma autoridade desconhecida
Nós vamos escrever um programa para tentar estabelecer uma conexão e comunicação com o servidor HTTPS.
//gohttps/4-https/client1.go
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://localhost:8081")
if err != nil {
fmt.Println("error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
Executar este cliente, temos o seguinte erro:
$go run client1.go
error: Get https://localhost:8081: x509: certificate signed by unknown authority
Neste ponto, o log de erro do servidor também dá dicas:
2015/04/30 16:03:31 http: TLS handshake error from 127.0.0.1:62004: remote error: bad certificate
Obviamente, do ponto de vista do cliente o log, vá para perceber o padrão é cliente-servidor para passar sobre a verificação do certificado digital, mas o cliente Nota: Este certificado é emitido por um desconhecido CA do!
Client1.go podemos modificar o código para que do lado do cliente ignorar a verificação de certificados:
//gohttps/4-https/client2.go
package main
import (
"crypto/tls"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://localhost:8081")
if err != nil {
fmt.Println("error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
, Certificado de servidor do cliente não serão verificados, definindo a verdade a InsecureSkipVerify tls.Config. Aplicação dos resultados também confirmou isso:
$go run client2.go
Hi, This is an example of http service in golang!
http pedido conjunto cabeçalho
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"encoding/json"
)
func main() { //生成client 参数为默认
client := &http.Client{}
//生成要访问的url
url := "http://somesite/somepath/"
//提交请求
reqest, err := http.NewRequest("GET", url, nil)
//增加header选项
reqest.Header.Add("Cookie", "xxxxxx")
reqest.Header.Add("User-Agent", "xxx")
reqest.Header.Add("X-Requested-With", "xxxx")
if err != nil {
panic(err)
}
//处理返回结果
response, _ := client.Do(reqest)
defer response.Body.Close()
}
http pedidos de proxy
package main
import (
"crypto/tls"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
// http proxy get方法
func httpProxyGet(dataUrl, proxyIp string) (data []byte, err error) {
transport := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, //ssl证书报错问题
DisableKeepAlives: false, //关闭连接复用,因为后台连接过多最后会造成端口耗尽
MaxIdleConns: -1, //最大空闲连接数量
IdleConnTimeout: time.Duration(5 * time.Second), //空闲连接超时时间
Proxy: http.ProxyURL(&url.URL{
Scheme: "http",
Host: proxyIp,
}),
}
// 设置代理方式二
//proxyUrl, _ := url.Parse("http://" + proxyIp)
//transport.Proxy = http.ProxyURL(proxyUrl)
// 创建http客户端
client := &http.Client{
Timeout: time.Duration(30 * time.Second),
Transport: transport,
}
request, err := http.NewRequest("GET", dataUrl, nil)
if err != nil {
return
}
// 请求数据
resp, err := client.Do(request)
if err != nil {
err = fmt.Errorf("request %s, proxyIp: (%s),err: %v", dataUrl, proxyIp, err)
return
}
defer resp.Body.Close()
// 读取数据
buf := make([]byte, 128)
data = make([]byte, 0, 2048)
for {
n, err := resp.Body.Read(buf)
data = append(data, buf[:n]...)
if err == io.EOF {
break
}
if err != nil {
continue
}
}
return
}
func main() {
data, err := httpProxyGet("http://www.baidu.com/", "89.22.11.55:9000")
if err != nil {
println(err)
return
}
fmt.Println(string(data))
}
Programação websocket
O que é WebSocket
- protocolo WebSocket é uma comunicação duplex completa através de uma única ligação TCP
- WebSocket permite a troca de dados entre o cliente eo servidor mais fácil, permitindo que o servidor para o cliente empurrar ativamente dados
- Na API WebSocket, o navegador eo servidor só precisa completar um aperto de mão, você pode criar diretamente uma conexão persistente entre os dois, e transmissão de dados bidirecional
- Você precisa instalar pacotes de terceiros:
- cmd em:
go get -u -v github.com/gorilla/websocket
- cmd em:
exemplo WebSocket
o servidor
package main
import (
"github.com/gorilla/websocket"
"log"
"net/http"
)
var upgrader = websocket.Upgrader{ // 配置websocker选项
// 允许websocket跨域
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func echo(w http.ResponseWriter, r *http.Request) {
c, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
defer c.Close()
for {
mt, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", message)
err = c.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
}
}
func main() {
log.SetFlags(0)
http.HandleFunc("/echo", echo)
log.Fatal(http.ListenAndServe("127.0.0.1:8081", nil))
}
cliente html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>websocket demo</title>
</head>
<body>
<table>
<tr>
<td valign="top" width="50%">
<p>
Click "Open" to create a connection to the server, "Send" to send a
message to the server and "Close" to close the connection. You can
change the message and send multiple times.
</p>
<form>
<button id="open">Open</button>
<button id="close">Close</button>
<input id="input" type="text" value="Hello world!" />
<button id="send">Send</button>
</form>
</td>
<td valign="top" width="50%">
<div id="output"></div>
</td>
</tr>
<script>
window.addEventListener('load', function(evt) {
var output = document.getElementById('output')
var input = document.getElementById('input')
var ws
var print = function(message) {
var d = document.createElement('div')
d.innerHTML = message
output.appendChild(d)
}
document.getElementById('open').onclick = function(evt) {
if (ws) {
return false
}
ws = new WebSocket('ws://127.0.0.1:8081/echo')
ws.onopen = function(evt) {
print('OPEN')
}
ws.onclose = function(evt) {
print('CLOSE')
ws = null
}
ws.onmessage = function(evt) {
print('RESPONSE: ' + evt.data)
}
ws.onerror = function(evt) {
print('ERROR: ' + evt.data)
}
return false
}
document.getElementById('send').onclick = function(evt) {
if (!ws) {
return false
}
print('SEND: ' + input.value)
ws.send(input.value)
return false
}
document.getElementById('close').onclick = function(evt) {
if (!ws) {
return false
}
ws.close()
return false
}
})
</script>
</table>
</body>
</html>