2015年5月31日 星期日

如何讓顧客介紹顧客

曾經為亞洲四小龍的我們,如今只剩經濟蕭條和競爭激烈,在一遍腥風血雨的比價中,利潤更是薄如絲,如何保存碩果的顧客們,就是一門絕學,為何如此說?顧客再次回顧率的機會遠遠大於初次登門的顧客,有一句名言:『好事不出門,壞事傳千里』,但是拜網路資訊所賜…好事傳百里,壞事全世界知,如何創造好口碑,好文化,才能加強顧客的信任感,更一層次的關係,就是顧客幫你介紹顧客,這也是所有經營者們最重要議題。

  有人統計過每個人對於昨天才發生過記憶只會保留23% 昨天的記憶,換句話說,如果沒有強化顧客的關係,顧客一下子就把你忘了,當然回顧率,也下降許多,即使第一次登門顧客對公司的產品或服務感到滿意,但時間一久,仍然會忘記,所以說…要讓顧客的記得你的好方法,就是當顧客的男女朋友……………………,筆者有點太誇張了…要讓顧客感受到你的存在,又不會像蒼蠅煩人…最重要的是『好的服務』和『產品本質』,才會讓顧客成為忠誠客戶的不變定理。

  說了這麼多,口水也快說乾了,雖然大家都知道維持顧客很重要, 但重點是how,如何去做? 有句話說:『一種米養百款人』,意思是每個人個性不同,有的喜歡佔便宜、有的喜歡與眾不同、有的喜歡節省時間、有的喜歡貼心服務,依不同喜好作註記,促銷時,可以從中篩選顧客作為客製化的行銷,就更能事半功倍,以下僅是作者淺見僅供參考,希望有助於經營者們提升經營績效。

1.    釣大魚請先放餌:針對貪小便宜的顧客們,減價促銷,但前提要在社群網站上貼上對公司有正面文章,幫忙作宣傳廣告,也許能真正吸引對企業更有實質幫助的顧客。
2.    善用資源:針對現有的顧客,搜集相關的情報,針對服務和產品做不滿意調查,即可得知改善哪些方向,當然,資訊的有效性和即時性也是需要特別注意的。
3.    公司文化:建立公司的形象,加強員工的穩定性才能達到員工服務提升、顧客滿意度也漸漸提昇,企業才能更穩定客源,三贏的面向,如果企業能以更廣大的視野角度,不追短暫眼前的利益,能夠以創新角度開發市場,將能更能上一層樓。

  留住好的顧客,不單單為企業增加利益,更能幫助企業們提升應有品質和服務,企業也應該思考如何增加與顧客之間的互動,不應該是局限於顧客關懷話題,當企業要求員工付出關懷關心顧客之前,也能多一份用心在員工身上,讓三方面真正達到黃金三角點,企業才能真正的正成長。

參考文獻

2015年5月28日 星期四

如何使用node.js 實作WebRTC

一、    Socket訊息傳遞

    兩個端點之間的連線建立時,兩個端點需要一直與socket Server互相傳遞的訊息,透過SDPOfferAnswer 的協定,建立雙方通道才能進行P2P資料傳輸。
以上圖供參考,如有錯誤,請見諒


二、    安裝Socket.IO








三、    Node.js 建立的Socket Server


var http = require('http'); 
var fs = require('fs');
var port = "8000";
var ip = "192.168.1.63";
var socket_io = require("socket.io");  //注入socket.io
function onRequest(request, response) {
    console.log("Request received.");   
    response.writeHead(200, { 'Content-Type': 'text/html' });
    response.write('<head><meta charset="utf-8"/></head>');          
    fs.readFile('index3.html', 'utf8', function (err, data) {
        if (err) {
            return console.log(err);
        }
        response.end(data);
    });
}

var server =http.createServer(onRequest).listen(port, ip); 
var io = socket_io.listen(server);  // socket.io 注入http ;  client端呼叫http 時,socket.io 也會啟動
io.sockets.on('connection', function (socket) {   
    // 如果有接收到offer 訊息,立即傳送廣播封包,發送offer 訊息給client
    socket.on('offer', function (data) {
        socket.broadcast.emit('offer', { sdp: data.sdp });
    });
    // 如果有接收到answer 訊息,立即傳送廣播封包,發送answer 訊息給client
    socket.on('answer', function (data) {
        socket.broadcast.emit('answer', { sdp: data.sdp });
    });
// 如果有接收到ice 訊息,立即傳送廣播封包,發送ice 訊息給client
    socket.on('ice', function (data) {
        socket.broadcast.emit('ice', { candidate: data.candidate });
    });  
   // 如果有接收到hangup 訊息,立即傳送廣播封包,發送hangup訊息給client
    socket.on('hangup', function () {
        socket.broadcast.emit('hangup', {});
    });
});

四、    WebRTC程式範例  
 
網頁要嵌入socket.io.js 檔案,版本有差異檔案路徑也有所不同,目前作者的路徑在\node_modules\socket.io\node_modules\socket.io-client\socket.io.js 將它copy\node_modules\socket.io\ 路徑

  <script src="/socket.io/socket.io.js"></script>


  <script>
        var socket = io.connect('http://192.168.1.63:8000');
        //針對moliza 有些仍未整合統一規格,所以針對各家瀏覽器,仍需特殊處理
        var RTCSessionDescription = window.mozRTCSessionDescription
|| window.webkitRTCSessionDescription || window.RTCSessionDescription;
        var RTCIceCandidate = window.mozRTCIceCandidate || window.webkitRTCIceCandidate
|| window.RTCIceCandidate;

        var mediaConstraints = {
            "mandatory": {
                "OfferToReceiveAudio": true,
                "OfferToReceiveVideo": true
            }
        };

        var localStream;
        var localPeerConnection;
        var remotePeerConnection;
        var localVideo = document.getElementById('localVideo');
        var remoteVideo = document.getElementById('remoteVideo');              
        var startButton = document.getElementById('startButton');
        var callButton = document.getElementById('callButton');
        var hangupButton = document.getElementById('hangupButton');
        startButton.disabled = false;
        callButton.disabled = true;
        hangupButton.disabled = true;
        startButton.onclick = start;
        callButton.onclick = call;
        hangupButton.onclick = hangup;

        function gotStream(stream) {
            localVideo.src = URL.createObjectURL(stream);
            localStream = stream;
            callButton.disabled = false;
        }

//針對moliza 的規格,所以要特殊處理
      function getPeerConnection() {
                if(navigator.userAgent.indexOf("Chrome") != -1 )
                {
                    localPeerConnection = new webkitRTCPeerConnection(null);
                    remotePeerConnection = new webkitRTCPeerConnection(null);
                }             
                else if(navigator.userAgent.indexOf("Firefox") != -1 )
                {
                    localPeerConnection = new mozRTCPeerConnection(null);
                    remotePeerConnection = new mozRTCPeerConnection(null);
                }
        }

        function start() {
            startButton.disabled = true;
            navigator.getUserMedia = navigator.getUserMedia ||
              navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
            navigator.getUserMedia({
                video: true
            }, gotStream,
              function (error) {
                  trace('navigator.getUserMedia error: ', error);
              });
        }

        function call() {
            callButton.disabled = true;
            hangupButton.disabled = false;          
         getPeerConnection(); //建立RTCPeerConnection 的函式(fireFox 瀏覽器另外處理)
         remotePeerConnection.onaddstream = gotRemoteStream; //產生串流
            localPeerConnection.addStream(localStream);
           
            //準備訊息交換的訊息
            localPeerConnection.createOffer(function (sdp) {
                localPeerConnection.setLocalDescription(sdp, function () {
                    socket.emit('offer', { sdp: sdp }); ,建立 offer 訊號, 等待socket 回傳offer
                },Error);
            }, function () {
                console.log('create offer error.');
            }, mediaConstraints);
        }
             
        function gotRemoteIceCandidate(event) {          
            if (!!event.candidate) {
                socket.emit('ice', { candidate: e.candidate });
            }
        }
    
        function hangup() {
            localPeerConnection.close();
            remotePeerConnection.close();
            localPeerConnection = null;
            remotePeerConnection = null;
            hangupButton.disabled = true;
            callButton.disabled = false;
        }

        function gotRemoteStream(event) {
            remoteVideo.src = URL.createObjectURL(event.stream);
        }
        // 建立 ice ,準備連線的前置作業
        socket.on('offer', function (data) {
            remotePeerConnection.onicecandidate = function (e) {
                if (!!e.candidate) {
                    socket.emit('ice', { candidate: e.candidate });  // 發送出ice 訊息等待socket回傳ice訊息
                }
            };
            var offer = new RTCSessionDescription(data.sdp);  // 預備要交換的訊息
            remotePeerConnection.setRemoteDescription(offer, function () {
// 遠端電腦接收offer訊息後,要回傳answer訊息,並開始進始多媒體的傳輸作業
            remotePeerConnection.createAnswer(function (sdp) { 
                    remotePeerConnection.setLocalDescription(sdp, function () {
                        socket.emit('answer', { sdp: sdp }); //送出socket answer 等待,socket 回傳answer 訊息
                    }, function (e) {
                        console.log('set local description error: ' + e);
                    });
                }, function (e) {
                    console.log('create answer error: ' + e);
                }, mediaConstraints);
            }, function (e) {
                console.log('set remote description error: ' + e);
            });
        });

        // 接收遠端電腦回傳的answer 訊息
        socket.on('answer', function (data) {
            localPeerConnection.setRemoteDescription(new RTCSessionDescription(data.sdp));  //準備多媒體傳輸通道
        });

       // 接收回傳ice 訊息,將自己本地端的ICE 訊息回傳
        socket.on('ice', function (data) {         
            localPeerConnection.addIceCandidate(new RTCIceCandidate(data.candidate));
        });
  }
    </script>

    目前作者想測試桌機瀏覽器Chrome 43版本 和Chrome for Android的連線,電腦無法接收到手機傳出的視訊,測試Firefox 38 firefox for Android 狀況也是一樣,截取自fireFox 的錯誤訊息為ICE failed, see about:webrtc for more details


手機卻成功接收來自電腦傳送的視訊串流…   這真是太神奇了傑克!