使用Node.js获取Bitpoint的价格并返回响应
环境
Unity 2013.3.0p4
Windows10
Unity 2013.3.0p4
Windows10
概述
我试图从Unity访问Bitpoint价格信息的websocket API,但不成功。因此,我使用NodeJs中的SockJs-Client来获取信息,并建立了一个Http服务器,以便向发出Http请求的Unity返回信息。
谷歌云计算引擎的配置,WinScp的配置
请根据以下指南进行设置:
记下服务器的IP地址(外部IP)
使用WinScp登录到Google Compute Engine的VM实例
上传程序
使用WinScp上传以下所述的”bitpoint.js”和”serverBitpoint.sh”文件并授予执行权限。
– 在WinScp上选择文件,从属性中进行操作。
安装NodeJs
通过SSH登录到服务器并打开Putty命令行
输入”sudo yum install -y nodejs”
提升openssl
输入”sudo yum update openssl”
下载模块
在JavaScript内下载引用的模块。
・输入”npm init”
会被要求输入各种信息,直接按下回车键
将生成package.json文件
・输入”npm install -save XXX”
使用-save选项将模块信息保存在package.json中
XXX是模块的名称
在Bitpoint.js中被require的模块
输入”node Bitpoint.js”时出现错误所缺少的模块
request
sockjs-client
date-utils
※可能还有其他被报错的模块
执行程序
“输入「nohup ./serverBitpoint.sh &」”
程式
我正在获取访问令牌,但这只是一个虚假的值。
用户名和密码也是虚假的。
不知为何只有在执行后才能与WebSocket通信(可能是我的错觉)。
bitpoint.js
const Crypto = require("crypto");
const Request = require('request');
const SockJS = require('sockjs-client');
const Http = require('http');
const Url = require('url');
const Qs = require('querystring');
require('date-utils');
const USERNAME = "hogehoge@hoge.com";
const PASSWORD = "fugafuga";
var _server;
Main();
function Main()
{
GetAccessToken();
CreateHttpServer();
}
function GetAccessToken()
{
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var sha256 = Crypto.createHash('sha256');
sha256.update(PASSWORD);
var hash = sha256.digest('hex')
Request.get(`https://public.bitpoint.co.jp/bpj-api/login?username=${USERNAME}&password=${hash}`, (error, response, body) =>
{
var accessToken = JSON.parse(body)['access_token'];
console.log( 'access_token', accessToken );
});
}
function CreateHttpServer()
{
_server = Http.createServer();
_server.on('request', function( req, res )
{
console.log("Method = ", req.method);
console.log("STATUS: ", res.statusCode);
console.log("Content-Type: ", res.getHeader("Content-Type") );
var getParams = Url.parse( req.url, true );
console.log( "Get:", getParams.query );
if( req.method == 'POST' )
{
var body='';
req.on( 'data', function( data )
{
body += data;
});
req.on( 'end', function()
{
var postParams = Qs.parse( body );
console.log( "Post:", postParams );
HttpResponse( req, res, getParams, postParams );
});
}
else
HttpResponse( req, res, getParams, null );
});
_server.listen(8080)
console.log('Start Server');
}
function HttpResponse( req, res, getParams, postParams )
{
var Responses =
{
"Default": function ()
{
res.writeHead(200, {'Content-Type': 'application/json'});
var now = new Date().toFormat("YYYYMMDDHH24MISS");
res.end( `{ "time":"${now}" }` );
},
"leverageTwoWay": function ()
{
var accessToken = ( getParams.query[ "access_token" ] ) ? getParams.query[ "access_token" ] : "";
RequestLeverageTwoWay( accessToken, postParams, function( response )
{
res.writeHead(200, {'Content-Type': 'application/json'});
res.end( response );
});
}
}
var uri = Url.parse(req.url).pathname;
if (uri === "/")
{
Responses["Default"]();
return;
}
else if (uri === "/leverageTwoWay")
{
Responses["leverageTwoWay"]();
return;
}
}
function RequestLeverageTwoWay( accessToken, postParams, onResponse )
{
var response = '{ "error":"" }';
if( accessToken == "" )
{
response = '{ "error":"accessToken" }';
console.log( response );
onResponse( response );
return;
}
if( postParams == null )
{
response = '{ "error":"postParams" }';
console.log( response );
onResponse( response );
return;
}
var options = postParams;//{ 'server': '{"currencyCd1":"BTC","currencyCd2":"JPY"}' };
const sock = new SockJS(`https://public.bitpoint.co.jp/bpj-api/leverageTwoWay?access_token=${accessToken}`, null, options );
sock.onopen = function()
{
console.log( "Open:", sock.url );
};
sock.onmessage = function(e)
{
console.log( "Message:", e.data );
var now = new Date().toFormat("YYYYMMDDHH24MISS");
response = `{ "updatetime":"${now}", "data":${e.data} }`;
sock.close();
};
sock.onclose = function()
{
console.log( "Close:", sock.url );
onResponse( response );
};
}
服务器 Bitpoint.sh
#!/bin/bash
node bitpoint.js
请用母语中国话改写以下内容,仅需给出一个选项:
客户端程序
调用ApiLogin.Request,并获取AccessToken。
调用ApiLeverageTwoWay.Request,从建立的服务器获取价格信息。
返回的json可以通过某种解析器转换成类或其他形式。
获取访问令牌
“XXXX, YYYY”是登录Bitpoint时使用的电子邮件地址和密码
Assets/ApiLogin.cs
public class ApiLogin
{
public static Coroutine Request( ExchangeBitpoint exchange, UnityAction<string> onResponse )
{
var sha256 = SHA256.Create();
var hash = sha256.ComputeHash( Encoding.ASCII.GetBytes( YYYY ) );
var password = BitConverter.ToString( hash ).Replace("-", "").ToLower();
var param = new Dictionary<string, string>();
param[ "username" ] = XXXX;
param[ "password" ] = password;
var query = exchange.GenerateFormParameter( param );
var api = "/login";
return exchange.Request( RequestType.Get, api + '?' + query, null, onResponse );
}
public class Response
{
public string access_token { get; set; }
}
}
资产/ ApiLeverageTwoWay.cs
public class ApiLeverageTwoWay
{
public static Coroutine Request( ExchangeBitpoint exchange, string accessToken, UnityAction<string> onResponse )
{
var query = "{ \"currencyCd1\":\"BTC\", \"currencyCd2\":\"JPY\" }";
var api = "/leverageTwoWay";
return exchange.Request( RequestType.RelayPost, api + "?access_token=" + accessToken, query, onResponse );
}
public class Response
{
public class Datum
{
public string currencyCd1 { get; set; }
public string currencyCd2 { get; set; }
public decimal seq { get; set; }
public decimal buySellCls { get; set; }
public string indicator { get; set; }
public decimal price { get; set; }
public decimal openPrice { get; set; }
public decimal highPrice { get; set; }
public decimal lowPrice { get; set; }
public decimal preClosePrice { get; set; }
public string priceDate { get; set; }
public string openPriceDate { get; set; }
public string highPriceDate { get; set; }
public string lowPriceDate { get; set; }
public string preClosePriceDate { get; set; }
public decimal change { get; set; }
public decimal changeRate { get; set; }
}
public string updatetime { get; set; }
public string error { get; set; }
public List<Datum> data { get; set; }
}
}
在Assets/ExchangeBitpoint.cs文件中,
当请求类型为「RequestType.RelayPost」时,设置自身建立的服务器被调用,并将服务器的IP地址填入XXXX。
using System;
using System.Collections;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Text;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
public enum RequestType
{
Get,
Post,
Delete,
RelayPost, //Bitpoint
}
public class ExchangeBitpoint : MonoBehaviour
{
private RemoteCertificateValidationCallback _remoteCertificateValidationCallback = new RemoteCertificateValidationCallback( ( sender, certificate, chain, sslPolicyErrors ) => { return true; } );
public string GenerateFormParameter( Dictionary<string, string > dictForm )
{
string formParam = "";
var count = dictForm.Count;
var index = 0;
foreach( var pair in dictForm )
{
formParam += pair.Key + "=" + pair.Value;
index++;
if( index < count )
formParam += "&";
}
return formParam;
}
public Coroutine Request( RequestType type, string path, object query, UnityAction<string> onResponse, int timeout = 0 )
{
return StartCoroutine( OpRequest( type, path, query as string, onResponse, timeout ) );
}
protected IEnumerator OpRequest( RequestType type, string path, string query, UnityAction<string> onResponse, int timeout )
{
var url = "";
if( type != RequestType.RelayPost )
url = "https://public.bitpoint.co.jp/bpj-api" + path;
else
url = "http://XXXX:8080" + path;
var prevCertCallback = ServicePointManager.ServerCertificateValidationCallback;
ServicePointManager.ServerCertificateValidationCallback = _remoteCertificateValidationCallback;
var httpRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create( url );
switch( type )
{
case RequestType.Get:
httpRequest.Method = "GET";
break;
default:
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
byte[] bodyRaw = ( query != null ) ? Encoding.UTF8.GetBytes( query ) : null;
httpRequest.ContentLength = bodyRaw.Length;
var isRequest = false;
httpRequest.BeginGetRequestStream( ( ar ) =>
{
System.IO.Stream reqStream = httpRequest.EndGetRequestStream( ar );
//送信するデータを書き込む
reqStream.Write( bodyRaw, 0, bodyRaw.Length );
reqStream.Close();
isRequest = true;
}, null );
while( isRequest == false )
yield return null;
break;
}
string text = null;
bool isResponse = false;
httpRequest.BeginGetResponse( ( ar ) =>
{
var response = (System.Net.HttpWebResponse)httpRequest.EndGetResponse( ar );
var statusCode = (int)response.StatusCode;
System.IO.Stream resStream = response.GetResponseStream();
//受信して表示
System.IO.StreamReader sr = new System.IO.StreamReader( resStream, System.Text.Encoding.UTF8 );
text = sr.ReadToEnd();
sr.Close();
// response.Close();
isResponse = true;
}, null );
while( isResponse == false )
yield return null;
ServicePointManager.ServerCertificateValidationCallback = prevCertCallback;
if( onResponse != null )
onResponse( text );
yield break;
}
}
请参照以下内容。
海豹部队