Although PhantomJS version 1.9 does have WebSocket support, that support is limited to the hixie-76 draft of the protocol. PhantomJS 2.0 is scheduled to include the more modern RFC 6455 version of WebSockets. When writing scripts for PhantomJS that intend to use WebSocket connections, we must ensure that the server supports the hixie-76 version of the protocol.
package main import ( "bufio" "code.google.com/p/go.net/websocket" "github.com/garyburd/redigo/redis" //"github.com/davecgh/go-spew/spew" "crypto/md5" "encoding/hex" "io" "net/http" "os" "strconv" "strings" "time" ) const PS = string(os.PathSeparator) const PH = "/" var ( pwd, _ = os.Getwd() JSON = websocket.JSON Message = websocket.Message ActiveClients = make(map[ClientConn]int64) redis_host string rdPool *redis.Pool Upload_Dir string ) type ClientConn struct { websocket *websocket.Conn clientIP string } func init() { f, err := os.Open("config") if err != nil { panic(err) } else { defer f.Close() } buf := bufio.NewReader(f) line, err := buf.ReadString('\n') if err != nil || io.EOF == err { panic(err) } else { redis_host = strings.TrimSpace(line) rdPool = initRedis(redis_host) } line, err = buf.ReadString('\n') if err != nil || io.EOF == err { panic(err) } else { Upload_Dir = strings.TrimSpace(line) } } func SockServer(ws *websocket.Conn) { var err error var clientMessage string var serverMessage string defer func() { if err = ws.Close(); err != nil { pp("Websocket could not be closed", err.Error()) } }() client := ws.Request().RemoteAddr pp("Client connected:", client) sockClient := ClientConn{ws, client} ActiveClients[sockClient] = time.Now().Unix() pp("Number of clients connected:", len(ActiveClients)) for { err = Message.Receive(ws, &clientMessage) if err != nil { pp("Websocket Disconnected waiting", err.Error()) delete(ActiveClients, sockClient) pp("Number of clients still connected:", len(ActiveClients)) clientMessage = "" return } else { if clientMessage == "GET" { ret, err := redis.Strings(RedisExec(rdPool.Get(), "BLPOP", "screenshot:queue", 30)) if len(ret) == 2 && err == nil { url := ret[1] h := md5.New() h.Write([]byte(url)) name := hex.EncodeToString(h.Sum(nil)) subDir := strconv.Itoa(time.Now().Year()) + PS + strconv.Itoa(int(time.Now().Month())) os.MkdirAll(Upload_Dir+subDir, 0777) filename_full := Upload_Dir + subDir + PS + name serverMessage = filename_full + "|" + url pp("pop queue ok.", client, serverMessage) if err = Message.Send(ws, serverMessage); err != nil { pp("Could not send message to ", client, err.Error()) } } else { p("pop queue error.", client, err.Error()) if err = Message.Send(ws, "NULL"); err != nil { pp("Could not send message to ", client, err.Error()) } } } else if clientMessage == "OPEN" { if err = Message.Send(ws, "OPEN"); err != nil { pp("Could not send message to ", client, err.Error()) } } else { //todo } clientMessage = "" } } } func main() { http.Handle("/socket", websocket.Handler(SockServer)) err := http.ListenAndServe("127.0.0.1:9527", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } }
phantomjs起多进程的,做一个服务器端screenshot的service非常简单,关键部分代码如下:
var page = require('webpage').create(), system = require('system'), address, output, size; var loop = function() { var ws = new WebSocket("ws://127.0.0.1:9527/socket"); ws.onopen = function(evt){ ws.send('OPEN'); //ws.send('GET'); console.log("Opened."); }; ws.onclose = function(evt){ console.log("Closed."); window.setTimeout(loop, 60000); }; ws.onmessage = function(evt){ console.log("Message:"+ evt.data); //ws.send(evt.data); if(evt.data!= "" && evt.data!= "OPEN"){ arr= evt.data.split('|'); if (arr.length== 2){ name= arr[0]+ ".png"; url= arr[1]; screenshot(url, name, ""); } } ws.send('GET'); }; ws.onerror = function(evt){ console.log("Error." + evt.data); }; };
有疑问加站长微信联系(非本文作者)
本文来自:CSDN博客
感谢作者:u013834131
查看原文:Handle inter-process communication between PhantomJS and Golang processes via hixie-76 websockets