LoginSignup
4
4

More than 5 years have passed since last update.

azureサーバーでwebsocket(socket.io)を動かす

Posted at

azureサーバーでsocket.io使おうとしたらnode.js込みで色々大変だったので記録

1環境

azure web apps
node.js(v4.0.0)
socket.io(v1.3.5)
とりあえず最小?環境で

2azureサーバー

スクリーンショット 2015-11-09 16.09.04.png

アプリケーション設定でwebソケットをオンにする

3デプロイするファイルの準備

サーバーにデプロイするフォルダのルートに
app.js(最初にこのファイルが読み込まれるっぽい。)
index.html(app.jsで読み込む場合)
web.config(以下のように用意)

web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
     This configuration file is required if iisnode is used to run node processes behind
     IIS or IIS Express.  For more information, visit:

     https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->

<configuration>
  <system.webServer>
    <!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->
    <webSocket enabled="false" />
    <handlers>
      <!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
      <add name="iisnode" path="server.js" verb="*" modules="iisnode"/>
    </handlers>
    <rewrite>
      <rules>
        <!-- Do not interfere with requests for node-inspector debugging -->
        <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
          <match url="^server.js\/debug[\/]?" />
        </rule>

        <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}"/>
        </rule>

        <!-- All other URLs are mapped to the node.js site entry point -->
        <rule name="DynamicContent">
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
          </conditions>
          <action type="Rewrite" url="server.js"/>
        </rule>
      </rules>
    </rewrite>

    <!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
    <security>
      <requestFiltering>
        <hiddenSegments>
          <remove segment="bin"/>
        </hiddenSegments>
      </requestFiltering>
    </security>

    <!-- Make sure error responses are left untouched -->
    <httpErrors existingResponse="PassThrough" />

    <!--
      You can control how Node is hosted within IIS using the following options:
        * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server
        * node_env: will be propagated to node as NODE_ENV environment variable
        * debuggingEnabled - controls whether the built-in debugger is enabled

      See https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config for a full list of options
    -->
    <!--<iisnode watchedFiles="web.config;*.js"/>-->
  </system.webServer>
</configuration>

参照:http://www.hanselman.com/blog/EnablingWebsocketsForSocketioNodeAppsOnMicrosoftAzure.aspx

どうやらIISが動いて邪魔するみたいなのでそれを無視して、node.jsを動かせ的な感じ?らしい
(これがなくてもnode.jsは動く。あくまでwebsocketを使う場合)

今回はこちらのソースを改変したもので、チャットサーバーを起動してみる。

app.js
var fs = require('fs');
var port = process.env.PORT || 8000;
var server = require('http').createServer(function(req,res){
  res.writeHead(200,{'Content-Type':'text/html'});
  var output = fs.readFileSync('./index.html','utf-8');
  res.end(output);
}).listen(port);
var io = require('socket.io').listen(server);

var userHash = {};

io.sockets.on('connection',function(socket){

  socket.on('connected',function(name){
    var msg = name + 'が入室しました';
    userHash[socket.id] = name;
    io.sockets.emit('publish',{value:msg});
    console.log('connected');
  });

  socket.on('publish',function(data){
    io.sockets.emit('publish',{value:data.value});
  });

  socket.on('disconnect',function(){
    if(userHash[socket.id]){
    var msg = userHash[socket.id] + 'が退出しました';
    delete userHash[socket.id];
    io.sockets.emit('publish',{value:msg});
    }
  });
});

改変点としては
var port = process.env.PORT || 8000
デプロイした環境ではprocess.env.PORTが動いて勝手にどうにかしてくれるらしい。
ローカル環境では勝手に8000が動くようになってるので、ここは各自自分のポートにすればおk
ついでにfs.readFileSync();には動かしたいファイルのパスを入力
./は現在のディレクトリ、一応

index.html
<html>
<head>
    <meta charset='utf-8'>
    <title>socket.io</title>
</head>
<body>
    <input type='text' id='msg_input' style='width:200px;'/>
    <button onclick='publishMessage();'>ツイート</button>
    <div id='msg'></div>
    <script src='./socket.io/socket.io.js'></script>
    <script type='text/javascript'>

        var socketio = io();

        socketio.on('connected',function(name){});
        socketio.on('publish',function(data){addMessage(data.value);});
        socketio.on('disconnect',function(){});

        function start(name){
            socketio.emit('connected',name);
        }

        function publishMessage(){
            var textInput = document.getElementById('msg_input');
            var msg = '[' + myName + ']' + textInput.value;
            socketio.emit('publish',{value:'hage'});
            textInput.value = '';
        }

        function addMessage(msg){
            var domMeg = document.createElement('div');
            domMeg.innerHTML = new Date().toLocaleTimeString() + ' ' + msg;
            msgArea.appendChild(domMeg);
        }

        var msgArea = document.getElementById('msg');
        var myName = Math.floor(Math.random() * 100) + 'さん';
        addMessage('あなたは' + myName + 'として入室しました');
        start(myName);
        </script>
    </body>
    </html>

こちらの改変点は
var socket.io = io();
とりあえずこうすればローカルでもazureでも動く

4最後に

デプロイに関しては少々長ったらしいのでこちら参照

何か間違いがあればお願いします

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4