2019年12月3日 星期二

node.js use websocket Chat Room sample

參考:https://www.nodebeginner.org/index-zh-tw.html

1. 開啟PowerShell並安裝
    npm install express       <- 框架
    npm install ws               <- websocket 

2. service.js

const WebSocket = require('ws');

const server = new WebSocket.Server({ port: 8080 });

server.on('open', function open() {
  console.log('connected');
});

server.on('close', function close() {
  console.log('disconnected');
});

server.on('connection', function connection(ws, req) {
  const ip = req.connection.remoteAddress;
  const port = req.connection.remotePort;
  const clientName = ip + port;

  console.log('%s is connected', clientName)

  ws.send("Welcome " + clientName);

  ws.on('message', function incoming(message) {
    console.log('received: %s from %s', message, clientName);
    
    server.clients.forEach(function each(client) {
      if (client.readyState === WebSocket.OPEN) {
        client.send( clientName + " -> " + message);
      }
    });
  });
});

3. client.html

<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<title>WebSocket Chat</title>
</head>

<body>
<script type="text/javascript">
var socket;
if (!window.WebSocket) {
window.WebSocket = window.MozWebSocket;
}
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:8080/ws");
socket.onmessage = function (event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + '\n' + event.data
};
socket.onopen = function (event) {
var ta = document.getElementById('responseText');
ta.value = "connection!";
};
socket.onclose = function (event) {
var ta = document.getElementById('responseText');
ta.value = ta.value + "connection close";
};
} else {
alert("你的浏览器不支持 WebSocket!");
}

function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState == WebSocket.OPEN) {
socket.send(message);
} else {
alert("connection fail.");
}
}
</script>
<form onsubmit="return false;">
<h3>WebSocket Chat room:</h3>
<textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
<br>
<input type="text" name="message" style="width: 300px" value="Welcome">
<input type="button" value="Send" onclick="send(this.form.message.value)">
<input type="button" onclick="javascript:document.getElementById('responseText').value=''" 
value="Clean">
</form>
<br>
</body>

</html>

4. 伺服器端啟動service.js
    客戶端透過瀏覽器開啟client.html即可對話

sudo kill $(ps aux | grep 'app.js' | awk '{print $2}') sudo node service.js &

2019年10月31日 星期四

DotNet Core API sample by GitHub

久不用就會忘記,透過Visual Studio 的WEBAPI範例來搭配GitHub配合看版當個小型的敏捷開發的範本。

GitHub:

1. 下載Git by windows
進入官網 http://git-scm.com/

2. 建立看版做派工追蹤

3. 使用 Git Bash 建立專案
  cd c:\git\
  git init
  git add -f --all
  git commit
  git push

DotNet:
 

2. 取得DotNet Core 3.0 
使用Vistual Studio Install 的更新取得。 

3. 建立API專案 Code Sample

4. 透過team Explorer 做 commit & push

2019年10月2日 星期三

試算表的日期轉文字

在試算表的儲存格常常會依照所貼入的文字去轉換格式,但使用公式來處理時日期就會變轉成無意義的數字,這部分可以使用TEXT函數來轉換。

=TEXT(儲存格, "yyyy/mm/dd HH:MM:ss")

很容易忘掉,所以做個MEMO。

2019年9月17日 星期二

AWS EFS+EC2(AutoScaling+LoadBalance) 備忘

如標題其實在AWS使用Elastic Beanstalk就含有這些,而且還有其他不可忽視的優點,不過作為一位All in One的工程師,這些優點反而就有些礙手礙腳,尤其是處在那些天馬行空的需求上,真能專注在Code內且功能單純的專案,難啊...其實這些應該給專業的MIS去處理而不是找工程師去代理!!

EFS可擴展的共用檔案儲存服務,建立服務要注意的地方是:
1. 可用區域,選擇EC2會使用的區網網段
2. 安全群組,選擇相關的安全群組(最好是EC2使用的),另外ALL TCP Port須開放相關"可用區域"的區網網段,以便NFS協定運行。
3. DNS名稱是拿來連線用的,不同的檔案系統AWS會配給不同的DNS名稱。
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 DNS名稱:/ /掛載使用的資料夾

LoadBalance創建服務注意地方,唯一有卡關的在於ssl的CA憑證及PK密鑰的套用,這部分貼對位置就沒問題;另外可用區域的區網選擇也需搭配相關EC2使用的。

Auto Scaling根據設定自動對其進行擴展和縮減,建立服務要注意的地方是:
1. 創建使用的AMI檔,應已包含掛載EFS以便程式檔案更新時使用。當然AWS推薦的是CodeDeploy去處理;若干部落格推薦AMI手動更新,這些也是能考慮的...不在此篇討論。

※User Data記得加上...實測若沒有加上mount指令,則新的VM不會自動掛載~即便是原製作AMI的環境已掛載好的情況下。
#!/bin/bash
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 DNS名稱:/ /掛載使用的資料夾

2. 安全群組不要新建使用EFS相同的即可。
3. 增減條件與數量這部分依照實際需要去調整,目前使用的是CPU使用率超過60% 300秒就增加一台,最高增加到3台。
4. 另外要搭配LoadBalance分散風險,所以建立兩個AutoScaling Group關連到同一個LoadBalance。


後記: 就不截圖了AWS的文件還蠻多的且更新頻率高,有搭配相關超連結到時候需要再點選進去看即可。

2019年9月11日 星期三

網頁浮動式固定選單_CSS+JS

RWD風行,所以網站的前端要考慮的層面就多了很多,前端目前缺乏所以得自己來,浮動式固定選單挺常用到,備忘囉!!

CSS
<style>
  .navFixed {
  z-index: 10;         
  position: fixed;     
  top: 0;
  left: 0;
  margin-top: 0;
  min-width: 100%;
  opacity: 0.94;
  transition: opacity .5s ease-out; 
  }
</style>

JS
  <script type="text/javascript">
$(function() {
  $(window).scroll(function() {
    if ($(this).scrollTop() > 495)  {          /* 要滑動到選單的距離 */
       $('.dropdowns').addClass('navFixed');   /* 幫選單加上固定效果 */
    } else {
      $('.dropdowns').removeClass('navFixed'); /* 移除選單固定效果 */
    }
  });
});
  </script> 

HTML
  <div class="navFixed" ></div>

參考來源: https://edwardzou.blogspot.com/2017/09/fixMenu.html

透過gsutil進行 GCP Storage 至 AWS S3 操作

參考步驟:http://proanalyst.net/migrate-files-gcs-into-amazon-s3/

1. 建立一個VM並啟用SSH
2. 透過SSH連限制這個VM Instace
3.  寫入.boto

    echo [Credentials] >> ~/.boto
    echo aws_access_key_id = XXX >> ~/.boto
    echo aws_secret_access_key = OOOOO >> ~/.boto

4.  gsutil 指令

    資料夾搬移
    gsutil cp -r gs://BucketName/FolderName/ s3://BucketName/FolderName/
 
    特定檔案類型搬移
    gsutil cp *.jpg gs://BucketName/FolderName/ s3://BucketName/FolderName/


2019年8月23日 星期五

PHP import reCAPTCHA v3

早上得到反映Google reCAPTCHA循環出現輸入錯誤無法通過的消息,檢查中發現已經更新到 v3,他跟前代最大的差別就是不用再要求使用者與頁面互動,貌似會依照行為來計算分數判斷是否為機器人所為!!

套用步驟如下。
1. 申請KEY,進入此網站點選右上角進入Admin Console,依照步驟取得網站金鑰跟密鑰
 

2. 登入頁(HTML)

HEAD:
<script src="https://www.google.com/recaptcha/api.js?render=網站金錀"> </script>
<script>
grecaptcha.ready(function() {
  grecaptcha.execute('網站金錀', {action: 'homepage'}).then(function(token) {
    var recaptchaResponse = document.getElementById('recaptchaResponse');
    recaptchaResponse.value = token;
  });
});
</script>

FORM:
<input type="hidden" value="" name="recaptcha_response" id="recaptchaResponse">

3. 驗證頁(PHP)

if ( !$_POST ) exit;

$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = '密鑰';
$recaptcha_response = $_POST['recaptcha_response'];
//Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
$recaptcha = json_decode($recaptcha);
if($recaptcha->success==true){
   if($recaptcha->score >= 0.5) {
       //PASS
   } else {
       //BOT
   }
} else {
   //FAIL
}

4. 檢查~套用v3的頁面右下角會出現Google reCAPTCHA圖示,若無則表示有缺漏得檢查。

2019年8月2日 星期五

大量Time_wait的改善紀錄

因為AP架構設計的緣故,做了個Agent處理在Listen伺服器上檢查是否有需要處理的作業,頻繁的連線>檢查>關閉的作業,在客戶端Agent多的狀況下在伺服器端就會發現有許多Time_wait紀錄,這樣會造成WEB服務上的效能變差。

編輯 vim /etc/sysctl.conf

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30

然後執行  /sbin/sysctl -p 套用
  • net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉;
  • net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉;
  • net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
  • net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間
若是卡點在對資料庫的連線,那麼寫個shell script來kill process才能改善,單純結束連線解決不了問題。

define('MAX_SLEEP_TIME', 120);  

$hostname = "xxx";  
$username = "xxx";  
$password = "xxx";  

$err_level = error_reporting(0);
$connect = mysql_connect($hostname,$username,$password);
error_reporting($err_level); 
$result = mysql_query("SHOW PROCESSLIST", $connect);  
while ($proc = mysql_fetch_assoc($result)) {  
  if ($proc["Command"] == "Sleep" && $proc["Time"] > MAX_SLEEP_TIME) {  
    @mysql_query("KILL " . $proc["Id"], $connect);  
  }  
}   
mysql_close($connect);  

2019年8月1日 星期四

aliyun push to android 8 up 備忘

相關資源:
https://github.com/aliyun/alicloud-ams-demo/tree/master/OpenApi2.0/push-openapi-php-demo

這陣子在處理阿里推送上在Android 8裝置會收不到的狀態卡了許久,使用PushNoticeToAndroidRequest.php來進行推送都很迅速地在Android 8以下裝置收到,若是透過阿里後台的推送則全裝置都能順利收到,這就不會是APP設計的問題。

這部分問題要爬文建議透過百度搜尋來查找,比Google來的更豐富且針對些,應該是阿里雲屬於內地的產品吧! 即便在那斯達克上市也不能免俗。

總之關鍵點在於...以下參考~

//XXX必須與APP設定的一致
$request_android->setAndroidNotificationChannel("XXX");

ExtParameters設定:
//這是透過 PushNoticeToAndroidRequest.php 使用的設定
$request->setAndroidExtParameters("{\"key1\":\"value1\",\"api_name\":\"PushNoticeToAndroidRequest\"}");  

//這是透過 PushRequest.php 使用的設定
$request->setAndroidExtParameters("{\"k1\":\"android\",\"k2\":\"v2\"}"); 

//若設定成ALL則IOS相關設定需帶入
$request->setDeviceType("ANDROID");   

//這設定貌似也要加~不過數字上沒甚麼感覺
$request->setAndroidNotificationBarType(1);     //通知栏自定义样式0-100
$request->setAndroidNotificationBarPriority(1);     //通知栏自定义样式0-100

小結: 許多阿里後台端的問題都需有內地帳號才能發問(這個在台灣手機認證上就掛了),所以即便是呼叫OPENAPI順利得到MessageID對於"沒收到"這檔是也是無濟於事,打轉許久只能透過Try & Error排除。

另外曾考慮透過Dot NET來呼叫OPENAPI,不過在帶入appkey那行總是編譯失敗,nullable long<n> 未定義,改用建議的DLL會造成更多的變數定義錯誤,這是就神奇了~~目前無解。

補充:使用PushNoticeToAndroidRequest設定NotificationChannel沒意義,追蹤相關的code看來沒支援/強制寫入固定值在回傳的陣列裡也是靜悄悄,所以用PushRequest.php來推送即可。

2019年5月24日 星期五

aws s3 + CloudFront備忘

看中文頁面對照AWS官方英文說明剛開始會有些對不上,就寫個備忘文...留存

IAM USER設定:
新增一個使用者,取得程式使用的ID及KEY。

S3設定:

1. 建立S3服務,並設定儲存貯體名稱

2. 於屬性啟用靜態網站託管,取得靜態網站託管的終端節點

3. 設定儲存貯體政策{
    "Version": "YYXX-MM-DD",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::儲存貯體名稱/*"
        }
    ]
}

CloudFront設定:

源網域名稱:選擇剛建立s3的 靜態網站託管的終端節點源ID : 輸入儲存貯體名稱
可開啟SSL服務與HTTP導向HTTPS

PHP
下載資源
 composer require aws/aws-sdk-php
引用 
require '/path/to/vendor/autoload.php';

補充:
1. 如果要使用自訂的網域名,可透過DNS的CNAME設定來轉,並加入CloudFront的網域清單。
2. 如果持續顯示存取拒絕,可開放S3權限的"everyone"的讀取設定。

2019年3月28日 星期四

Cefsharp3 run at windows embedded standard

Cefsharp 是個可應用於Windows的chrome core的瀏覽器套件,近來搭配它做了一個WIN Form AP不過在發行時異常(尚未解),先用inno setup封裝頂著不過在更新上就沒有Visual Studio的方便。

佈署到客戶端在win 7 ~ X都順利運行,不過遺憾的是在客戶端有若干機器所使用的系統為 windows embedded standard,執行後直接跳出App Crash的訊息,自事件檢知器中看到的資訊貌似載入CefSharp.BrowserSubprocess.exe時出現的,研判應該跟multi thread設計有關吧,這部分只是猜測也無濟於事。

經GitHub更新到最近的73.X.X.X版本後直接編譯(use .NET Framework 4.6.2)的執行檔也是出現相同的狀況,後來在更新 Microsoft Visual C++ Redistributable至2015出現Setup Fails因此進行排除,順利安裝成功後再執行就順利啟動了(此期間安裝2012, 2013, 2017都順利,但無法啟動)。

處理這類線索有限的Debug過程是枯燥的,神隊友找到線索並順利排除真好。當下自己是直接在系統中安裝visual studio打算直接在windows embedded standard進行編譯,這好像也行但現在也只能先忙其他的,在緩緩囉。


2019年3月12日 星期二

CI cookies, session, cache memo

在CodeIgniter中頻繁使用Model在資料量大使用量高的EC網站是不好的選擇,可是EC網站的資料也不適合用靜態頁來處理,畢竟有許多互動的設計若是使用靜態頁那麼就失去意義了,某些(聯絡我們, 用戶條款)之類的到是很適合。
Ex. $this->output->cache($n);
放置在Controler的 $this->load->view($action, $data); 前。

首先在config/autoload.php裡面需要加入相關的help
$autoload['helper'] = array('cookie');

寫入
set_cookie('cookname', $cookdata, 3600);
取得
get_cookie('cookname')
刪除
delete_cookie('cookname');

於多網站共用Code的使用案例上,可是當使用prefix前綴來避免衝突/讀取錯誤的情事。
※全域設定可在 application/config/config.php 檔案中所設置的前綴  $config[‘cookie_prefix’]
※容量(size)大概4K使用,所以資料量大的話會無法儲存,存放於用戶端的瀏覽器內所以瀏覽器有限制存取時會無法使用。

首先在config/autoload.php裡面需要加入相關的help
$autoload['libraries'] = array('session');

寫入
$this->session->set_userdata('sessionname', $cookdata);
取得
$this->session->userdata('sessionname')
刪除
$this->session->unset_userdata('sessionname');
※ 容量(size)大概較Cookies大些但若是無法儲存則表示資料量超過容量限制,另外資料存放在記憶體內,伺服器記憶體管理務必注意。

cache:
$this->load->driver('cache'));


寫入$this->cache->save('cachename', $cookdata, 300); //300=5min
取得
$this->cache->get('cachename')
刪除
$this->cache->delete('cachename');
※ 使用檔案儲存所以資料量不用擔心,不過因為是FILE所以I/O讀取的效率就偏低。

2019年3月7日 星期四

HTML中的特殊符號對照表(備忘)

在寫入資料庫與檔案(靜態檔,資源檔)常因特殊字元造成載入/顯示上的異常,這個網頁列出相當多的對應可以提供需要時的查詢,PHP最常碰到的大概是單/雙引號造成的字串判斷異常,可以用以下sample code來排除。

$Value= str_replace("'", "&apos;", $Value);

2019年2月21日 星期四

CefSharp3 Multi Thread Add listen AddressChanged Event

原來使用的套件 Awesomium.NET 因為太久沒更新對於BootStrap4的支援已經跟不上了,所以選擇的替代方案是CefSharp3這個Open Source Core。

不意外的CefSharp3也是Chrome Base的可是導入在WIN AP上有完整的範例,版控更新上於GitHub也能看出他的活躍,總之這是要補紀錄在multi Thread增加EVENT的備忘,免得過段時間又忘記怎麼做。

首先增加要listen的FUNC
/// <summary>
/// 設定新分頁的url address變更的監聽
/// </summary>
private void setNewTab_addressCheangeEvent() {
            var control = GetCurrentTabControl();
            if (control != null)
            {
                control.Browser.AddressChanged += new EventHandler<AddressChangedEventArgs>(web_Auto_AddressChanged);
            }
}
//這個是把網址寫到指定的區域內
 private void web_Auto_AddressChanged(object sender, AddressChangedEventArgs e){
            SetTxt_Url(e.Address);
}

private delegate void str_Delegate(string str);
private void SetTxt_Url(string str) {
            if (InvokeRequired) {
                Invoke(new str_Delegate(SetTxt_Url), str);
                return;
            }
            TSL_url.Text = str;
}
接著於browserTabControl.TabPages.Add(tabPage); 之後加上 setNewTab_addressCheangeEvent();就會在每次新增的Tab都會去加入這EVENT的Listen。

這是以AddressChanged 觸發時的範例,其他的以此類推即可。

補充: 有趣的文章
JS處理修改URL但不跳轉的方法,在WEB POS接地氣上面來說對我幫助很大,節錄ing
var stateObj = { foo"bar" };
history.pushState(stateObj, """controler/function/variable");

2019年2月12日 星期二

Redmine SETUP Memo

Redmine是一套Open Source的專案管理系統,之前安裝的是2.6近期再檢視已經發行到4.0.1版了,進行升級的參考此頁面的步驟,無痛(補充1?)的升級完成。

後來發現升級4.0.1其實也不是那麼需要,主因是同事發現此樣板覺得與GitHub敏捷管理類似,需要套用~套用完畢之後發現沒有出現就覺得是新版的有,其實都是誤會...因為即便是升級完畢依舊是沒有,它是以plugin方式加入的,說明如下:

Agile plugin 有 Lite版本是免費的,其餘進階版本都是要另外收年費,填寫完email之後會收到下載與安裝教學的連結,很直觀不過安裝時會檢查是否安裝crm套件,這部分就得先安裝CRM套件後才能順利安裝Agile plugin。

補充1: 2.6 to 4.0.1 唯一出的問題是ruby的版本需 > 2,原先安裝的版本是 1.9.1,變更ruby的步驟參考此頁面處理,用RVM管理Ruby版本真是方便!! 至於安裝ruby會依照不同的環境有不同的方式,就不留存了。

補充2: 啟用Redmine方式依舊沒變在VM環境下小小不方便(logout就關掉了),所以很開心script方式還是可以使用,這部分方式就持續使用start_redmine.sh來啟用/關閉/重啟。

補充3: Tags  plugin 也是不錯用的套件,建議加裝。

2019年2月1日 星期五

LinePay oneTimeKey 備忘

導入LinePay在門市端會使用到oneTimeKey,就官方文件上的說明雖然給了範例碼但就少了個醍醐味,估狗上的資料一堆看到了這篇實作後打通任督二脈,總算把掛在頭上個把月的需求單給結了。

話說...怎麼是日文的呢? 可能是Line本來就是從日韓那邊來的吧,相對的英文論壇討論的資料就少得可憐,當然內地簡體字的文章挺多的,可在oneTimeKey討論上應該是應用的少也沒爬到關鍵文章。

總之...
amount很直覺的金額,不用.00也不用x100。
oneTimeKey真的只能用一次,即便沒付費成功在丟會回錯誤訊息。
ConfirmUrl可以設但實測用不到(埋Log)沒有官方觸發的紀錄。

另外要注意的地方是呼叫payment後取得transactionId再進行refund才會真正扣款付款完成。

2019年1月30日 星期三

htmlspecialchars vs strip_tags

CKEditor 是個好用的第三方元件,不過使用後就會有若干的缺點被放大出來,無論是安全上的問題或是資料儲放量爆炸等等...都是煩人的~不過其優點可以讓無止盡的客戶端需(要)求得以滿足(或應付)也是不得不的選擇。

在使用上有很多時候是被要求不要出現HTML TAG的,這時候這兩個 htmlspecialchars() 及 strip_tags()函式就被提出來囉!! 都是在做 HTML 輸出消毒但這兩者還是有所不同,參考說明節錄如下:

strip_tags() 是用來防君子,所有正規合法的 html 或 php 標籤,都將被濾除。
htmlspecialchars() 則是用來防小人,所有想借機偷渡的語法,也會被抓出來,例如onmouseover='...'。

所以如果是可控的資料來源(後台)那麼strip_tags會有效率些(快點),不可控的資料來源(前端)就嚴謹些準沒錯!!

2019年1月21日 星期一

2019年1月10日 星期四

刷新作業系統的DNS紀錄...備忘

清除本機DNS Cache的方法
一、Windows
打開你的Windows,開起搜尋框,打下cmd(或從附屬應用程式中找到命令提示字元)。當命令提示字元的黑底白字畫面跑出>的時候輸入ipconfig /flushdns,然後按下enter鍵。

二、Mac OS X
打開你的Mac OS,點擊畫面右上角的放大鏡圖示的Spotlight,輸入terminal(或終端機)。當終端機的白底黑字跑出$的時候,如果你是10.5以上版本請輸入:sudo dscacheutil -flushcache,不到10.5版本請輸入:lookupd -flushcache,如出現詢問密碼,請輸入您的系統密碼(同安裝程式時所輸入的密碼),輸入密碼時畫面並不會出現任何文字或*,請照打,打完按下Enter鍵。

三、Linux(Ubuntu) 
開起你的terminal輸入/etc/rc.d/init.d/nscd restart,或者sudo /etc/init.d/nscd restart。
如果執行上述指令卻出現command not found,代表您的系統尚未安裝nscd,請先執行sudo aptitude install nscd,安裝nscd,安裝完成後請重新執行第一點之指令 /etc/rc.d/init.d/rstatd,或者sudo /etc/init.d/nscd restart。

完成後DNS Cache應該已經清空囉。

2019年1月9日 星期三

微信支付 By API 異常排除

近期在套用微信支付API碰到"數位簽章校驗不通過"的回覆困擾許久,程式碼檢查再檢查與文件對應都看不出所以然來,在檢視機台終端交易密鑰的更新Log發現相同程式碼下不同的終端編號會有不同的結果,若干編號就是回校驗不通過。

經查API文件僅敘述簽名檔做好SHA256運算後再以base64編碼置入sign中,此一現象在此網誌所述雷同,於是在base64編碼後在加上urlencode()後傳出,問題就排除了。

$hashValue= hash('sha256', $string, TRUE);
$sign=urlencode(base64_encode($hashValue));

小記:系統整合尤其是透過API交換資料的情況下,這類問題往往很難從單一方面去排除,尤其在另一方(內地? 代理的銀行端? 有聽沒有懂的客戶? )已讀不回或不讀不回下僅能以trial and error方式來排除,恩恩...期間所遭遇個管理層級與客戶層級的質問心酸,只能共勉之...


2019年1月4日 星期五

處理 curl call error(77) error(60) 備忘!


這陣子發生呼叫API無回應但API也沒有LOG(所以是沒有呼叫到API),後來在WEB端的Log檔看到crul回傳 err 77的記錄。

這個狀況因為只出現在特定機器上,所以看來非佈署問題與程式碼bug,新客戶網站後來新增SSL,但只用service nginx reload讓他生效並未執行service php-fpm restart,檢視SERVER運行時間已經百餘日也沒重啟過,所已將php-fpm重啟後就不會再發生相同的錯誤回報。

補充: 頁面使用JQuery(非同步)機制雖然能減少與伺服器端的資料交換量,可若啟用CSRF機制時若timeout時間設定太短而頁面太久沒有reload,會造成瀏覽者有頁面沒反應的情況,這部分在設計時需要檢查回傳值若為token過期狀態,則須強制頁面reload更新token已利正確運行。

使用curl增加設定:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0)

使用file_get_contents增加設定:
$arrContextOptions=array(
"ssl"=>array(
    "verify_peer"=>false,
    "verify_peer_name"=>false,
  ),
);
file_get_contents($target,false,stream_context_create($arrContextOptions));