我决定探索(Golang)在听了有关它的讨论之后。我选择使用GO绘制实时外汇数据,因为处理实时FX数据是我的专业领域。
这是我发现的。
- 设置也许是最简单的
- 几乎没有问题的功能。
许多GO和其他语言专家将不同意我的第二个声明。即使在提到的两个领域中Python很弱,我也喜欢它(我可能会再做一次)。
您将需要以前的编程经验,互联网连接和电子邮件地址来沿本教程工作。
让我们开始
获取WebSocket API密钥
在配置GO环境之前,让我们从登录网站接收FX WebSocket API密钥。这是无薪的。登录帐户并保留它后,请创建API键。
设置环境
下载并设置首先从https://golang.org/doc/install。
我们需要采取以下三个简单步骤:
- 安装Golang时。打开命令提示符并输入以下内容:
go version
- 其次,您应该安装依赖项。
go get github.com/gorilla/websocket
- 现在是时候跑步了!
让我们开始编码!我们将从开发基本框架开始。当程序启动时,将调用函数main(),同时,我们将导入必要的库。我们将在此插图中采用以下内容:
// +build ignore
package main
import (
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
func main() {
//Add progrma content here
}
将添加几个变量,一个变量用于存储传入消息,另一个用于处理程序结束时处理中断事件。与其他几种语言中的缓冲区类似,这些变量是消息的导管。
GO中的通道可以是单向或双向的。为了很好地整理程序,我们将在中断变量中添加信号通知器。
messageOut := make(chan string)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
现在,我们将为WebSocket服务器连接生成URL并输出它,以便我们验证URL。
u := url.URL{Scheme: "wss", Host: "marketdata.tradermade.com", Path: "/feedadv",}
log.Printf("connecting to %s", u.String())
下一步是开发代码以连接到服务器并处理与连接相关的各种结果。创建后,我们会扫描错误,并通知用户,如果我们找到任何错误。
本节的最后一行添加了“ defer c.close()”,告诉程序在此方法完成后在此连接上调用CLOSE()。将最初的递延执行视为堆栈上的最终操作。
c, resp, err := websocket.DefaultDialer.Dial(u.String(), nil);
if err != nil {
log.Printf("handshake failed with status %d", resp.StatusCode)
log.Fatal("dial:", err)
}
//When the program closes close the connection
defer c.Close()
现在已经编写了管理连接的方法,它将从feed异步读取该过程,因为它是goroutine。它使用c读取消息时读取该消息。使用ReadMessage(),返回通知或错误。
收到消息时,首先对其进行测试以确定它是否是连接消息;如果是,则返回包含用户密钥和必要符号的字符串。该代码在收到错误时输出错误消息并离开。
发送了此消息后,客户将使用定价消息回复。在此图中,我们将消息打印到屏幕上,但是您可以在此处分析消息数据。
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
if string(message) == "Connected"{
log.Printf("Send Sub Details: %s", message)
messageOut <- "{"userKey":"YOUR_API_KEY", "symbol":"EURUSD"}"
}
}
}()
此程序的最终组件显得复杂,但实际上很简单。由于Goroutine是异步,因此不会锁定主线程。因此,如果没有本节,该程序将返回,您的饲料处理程序将停止。这种连续的循环用于保持程序的继续。
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case m := <-messageOut:
log.Printf("Send Message %s", m)
err := c.WriteMessage(websocket.TextMessage, []byte(m))
if err != nil {
log.Println("write:", err)
return
}
case t := <-ticker.C:
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
我们可以组合所有代码,指定您的API _KEY,然后将文件保存为WebSocketClient.go。
然后使用终端中的以下命令启动代码:
go run websocketClient.go
您可能会看到实时定价更新。您运行的第一个Websocket客户端已成功完成FX数据。
这是完整的应用程序代码:
// +build ignore
package main
import (
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
func main() {
//Create Message Out
messageOut := make(chan string)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := url.URL{Scheme: "wss", Host: "marketdata.tradermade.com", Path: "/feedadv",}
log.Printf("connecting to %s", u.String())
c, resp, err := websocket.DefaultDialer.Dial(u.String(), nil);
if err != nil {
log.Printf("handshake failed with status %d", resp.StatusCode)
log.Fatal("dial:", err)
}
//When the program closes close the connection
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
if string(message) == "Connected"{
log.Printf("Send Sub Details: %s", message)
messageOut <- "{"userKey":"YOUR_API_KEY", "symbol":"EURUSD"}"
}
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case m := <-messageOut:
log.Printf("Send Message %s", m)
err := c.WriteMessage(websocket.TextMessage, []byte(m))
if err != nil {
log.Println("write:", err)
return
}
case t := <-ticker.C:
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
另外,遍历我们的其他教程:
How To Write Your First Golang WebSocket Client
Your First Golang REST API Client