Jxck です。

自分のは動いてます。

> "channels.pop()" じゃなくて"{channelId: channels}"じゃ無いとサーバ側で判断できなかったみたいです。
元のソースは value を受け取って value.channelId だかになってましたが、オブジェクトである必要が無かったので、
自分のは文字列だけ送ってます。写し?間違えかと。コメントも読んでください。

> あとlocalhost・・・ほかのpcから動かしてました。
https://gist.github.com/4624554#comment-750044 コメント読んでもらってます?

元のソースが(クライアントは無かったけど) localhost ベタ書きだったんで合わせたんですが。。
ちなみに Socket.IO の connect は同一オリジンならパスだけで良いです。
ルートなら引数すらいらない。

io.connect("http://localhost:3000";) => io.connect();

書いちゃうとデプロイする時困るので、同一ホストの場合は書かないのが普通です。
(って話をコメントで指摘して修正しておくべきだったのか。。)


> で、もうひとつ質問なんですが・・・disconnectしていないソケットってどうなるんですか?
これなんか引っかかるんですが、 Socket.IO の disconnect してない接続という意味ですか?


> webは無理ですが、iphoneやandroidで接続した場合、nodeを停止して起動しても再度接続されます。
> もしかするとiphoneやandroidは接続しっぱなしだけかもしれませんが。
再接続って Socket.IO のリトライによる再接続のことですか?
Socket.IO は Socket.IO の接続が切断しても、何度もリトライしてサーバが復活したら再接続します。
"webはムリですが" の web ってたぶん PC ブラウザのこと?だと思うんですが、
PC ブラウザでもそれはなるはずです。


# 全体的に主語を書いて下さい。
# 「これ何を言ってるんだろう?」まで想像しながら答えるのはコストが高いので、
# そのせいで放置される質問も多いです。
# 丁寧すぎるくらい丁寧に説明して頂いたほうが、無駄な確認が減るのでいいと思います。
# あと、ソースベタ書きも読みにくいので、ある程度の量なら gist とかどっかに上げるとより読みやすいです。

Jxck

2013年1月25日 13:33 matton <[email protected]>:

> Jxckさん KOBAさん ありがとうございます。
>
> (同じサーバなのに、**わざわざ自分自身にソケットを経由するとか)
> バッチからのURLデータ渡しをクライアント処理と思い込んでいたのが問題でした。
> なのでクライアントとして接続する必要があると考え、ソケット経由に・・・
> そんな必要ないですね。
>
> 添付のソースで動く様になりました。ありがとうございます。
> ※現在mysqlの認証コードが入っています。
>
> ただ一点Jxckさんのindex.htmlに通知が届きません。
> 結構嵌ってしまいました・・・
> "channels.pop()" じゃなくて"{channelId: channels}"じゃ無いとサーバ側で判断できなかったみたいです。
> あとlocalhost・・・ほかのpcから動かしてました。
>
> 一通り、処理の内容を理解することができました。
>
> ありがとうございました。
>
> で、もうひとつ質問なんですが・・・disconnectしていないソケットってどうなるんですか?
> webは無理ですが、iphoneやandroidで接続した場合、nodeを停止して起動しても再度接続されます。
> もしかするとiphoneやandroidは接続しっぱなしだけかもしれませんが。
>
> なにか情報があれば教えて頂けないでしょうか?
>
> 申し訳ございません。質問ばかりで
>
>
> 2013年1月25日金曜日 1時36分16秒 UTC+9 Jxck:
>
>> Jxck です。
>>
>> KOBA からのでいいかなと思ったんですが、
>> 一応書いたので置いておきます。
>>
>> 最初は正直何がしたいのかよくわかりませんでした。
>> ただ、話を聞いてる感じだとやろうとしていることに対して、
>> やってることが過度に複雑なだけのようだったので。
>> (同じサーバなのに、**わざわざ自分自身にソケットを経由するとか)
>>
>> KOBA のも参考にしつつこんな感じかと。
>> (コメントを読んで下さい。)
>>
>> https://gist.github.com/**4624554 <https://gist.github.com/4624554>
>>
>>
>> 拙作ですが、翻訳してるのでこちらもご参考まで。
>>
>> http://jxck.github.com/socket.**io/#how-to-use<http://jxck.github.com/socket.io/#how-to-use>
>> https://github.com/Jxck/**socket.io/wiki/Rooms<https://github.com/Jxck/socket.io/wiki/Rooms>
>>
>> Jxck
>>
>> On Thursday, January 24, 2013 11:18:19 PM UTC+9, matton wrote:
>>>
>>> KOBA789 さん ご丁寧にありがとうございます。
>>>
>>> まず、socket.ioの標準機能を再度確認致します。
>>> 自身に接続してチャンネルに join している部分を見直します。
>>> 変数の件、知りませんでした。ありがとうございます。
>>> また、typo と思われたのは"_c"**付きの部分のことだと思います。
>>> ”socket_c ” とか "join_c"です。
>>> URL引数にてデータを受け取る為、データ受信の回数分http**.createServerが行われるのでその都度ではなく、自**
>>> 身に接続してチャンネルに **joinは一度だけとする為の部分です。
>>> それで最適な方法が思いつかず、**外側のスコープの変数による状態の受け渡しを行ってしまった次第**です。
>>>
>>> 明日になりますが、ソース見直し致します。
>>>
>>> よろしくお願いします。
>>>
>>>
>>> 2013年1月24日木曜日 22時33分49秒 UTC+9 KOBA789:
>>>>
>>>> KOBA789 です。
>>>>
>>>> なるほど、問題点の本質がわかりました。
>>>> まず、Socket.IO 
>>>> の仕様をよく知った方がよいかと思います。**標準機能を適切に活用することで解決できる問題は多くあります。**自身に接続してチャンネルに
>>>>
>>>> join している点に関してはこれで解決できます。
>>>> また、現状の外側のスコープの変数による状態の受け渡しでは、**ロックが必要になってしまいますし、クロージャを使える JavaScript
>>>> を用いた実装としては素直ではありません。**はっきり言って悪い実装ですから避けなければなりません。なお、**
>>>> 変数に無駄なスコープを持たせないことはバグの発見の容易さや、**バグの回避につながります。
>>>> 最後に重箱の隅をつつくようで申し訳ありませんが、**変数の初期化に空文字列を乱用するのは避けたほうがよいでしょう**。型に合わせた初期化をすることで、VM
>>>>
>>>> はメモリ確保に関して最適化をします。ですから、**不適切な型による初期化はパフォーマンス劣化につながります。
>>>> 以上の点を踏まえてソースを書き直すと以下のようにできるかと思**います。ただ、typo
>>>> と考えられるものなどがいくつかあり、**ソースの真意が読めない部分が多いため、**どうしても多くを憶測で書いてしまいました。**挙動が異なってしまっていたら申し訳ありません。
>>>>
>>>>
>>>> ==============================**==============================**==========
>>>>
>>>>
>>>> var http = require("http");
>>>> var url = require("url");
>>>>
>>>> function start(route,handle){
>>>>   function onRequest(request,response){
>>>>     var queryData = url.parse(request.url, true).query;
>>>>     var url_parts = url.parse(request.url,true);
>>>>     var query = url.parse(request.url, true).query;
>>>>     var pathname = url.parse(request.url).**pathname;
>>>>
>>>>     serversocket2("Appname",query)**;
>>>>     request.setEncoding("utf8");
>>>>
>>>>     request.addListener("end",**function(){
>>>>       route(handle,pathname,**response);
>>>>     });
>>>>   }
>>>>
>>>>   var server = http.createServer(onRequest).**listen(8080);
>>>>     //console.log("Serevr has sterted.");
>>>>
>>>>     // socket.io
>>>>   var io = require('socket.io').listen(**server);
>>>>
>>>>
>>>>   var archiveMessages = {};
>>>>   var channels = ['Appname'];
>>>>
>>>>   var appname = io.of('/appname');
>>>>   appname.on('connection', function(socket){
>>>>     console.log('connected: %s', socket.id);
>>>>
>>>>         // push available channel list
>>>>     socket.emit('available_**channel', channels);
>>>>
>>>>     socket.on('join', function(value){
>>>>       console.log('%s joined channel: %s', socket.id,
>>>> value.channelId);
>>>>
>>>>       socket.join(value.channelId);
>>>>       socket.set('channel_id', value.channelId);
>>>>     });
>>>>
>>>>     socket.on('post', function(message){
>>>>       socket.get('channel_id', function(err, channelId){
>>>>         console.log(' %s says<%s channel>: %s', socket.id, channelId,
>>>> message);
>>>>
>>>>       });
>>>>     });
>>>>
>>>>     socket.on('disconnect', function(){
>>>>       console.log('%s disconnected', socket.id);
>>>>       socket.get('channel_id', function(channelId){
>>>>         socket.leave(channelId);
>>>>       });
>>>>     });
>>>>
>>>>   });
>>>>
>>>>   function serversocket2(channelId,data){
>>>>     appname.in(channelId).emit('**user:message', data);
>>>>   }
>>>> };
>>>>
>>>> exports.start = start;
>>>>
>>>> 2013年1月24日 20:28 matton <[email protected]>:
>>>> > KOBA789さん返信ありがとうございます。
>>>> >
>>>> > はじめにnode初めて間もない為、**ソースが汚く申し訳ございません。
>>>> >
>>>> > setTimeoutを使用している理由は"**serversocket1"にてクライアント(自分)→**
>>>> サーバ(自分)にjoinを行っているのですが、**サーバ側の処理(socket.join)が終わる前に"**
>>>> serversocket2"が動くと"socket_c"**が空の状態となる為、setTimeoutを用いています。
>>>> > ※"socket_c"は"socket.join"**にてセットしています。
>>>> >  
>>>> > http.createServerの処理とsocket.**io<http://http.xn--createserversocket-7h4qxd8192fh5mg.io>間でコールバックをネストさせる方法はわかりませんでした。
>>>>
>>>> >
>>>> > お手数ですが、アドバイスよろしくお願いします。
>>>> >
>>>> >
>>>> > 2013年1月24日木曜日 19時36分23秒 UTC+9 KOBA789:
>>>> >>
>>>> >> KOBA789 です。
>>>> >>
>>>> >> 指摘したい点はたくさんありますが、まず1点だけ失礼します。
>>>> >> なぜ、わざわざ setTimeout による時間差によって実行順序を指定するということをしているの**でしょうか。
>>>> >>
>>>> >> 素直に考えて、**コールバックをネストさせることで対応するのが最善だと思うので**すが、そうしなかった理由を教えていただきたいです。**
>>>> その理由知ることでより踏み込んだアドバイスができると考えてい**ます。
>>>> >>
>>>> >> 2013年1月24日 11:03 matton <[email protected]>:
>>>> >> > お世話になります。 松尾と申します。
>>>> >> >
>>>> >> > node.jsにて下記の様な仕組みを作成しております。
>>>> >> >
>>>> >> > 現在、バッチプログラム(vs.net C#)にてDB監視を行い、**結果をクライアントに通知する仕組みを作成しています。
>>>> >> > 監視バッチ→node.js→ios/android
>>>> >> >
>>>> >> > として、node.js→ios/**androidはリアルタイム通知の為、soket-**
>>>> ioを使用しています。(※ちなみに監視バッチ→node.**jsはwebsocketが使用できない為、**URLにてデータを渡しています。
>>>> http://xxx?1=**a&2=B <http://xxx?1=a&2=B>)
>>>> >> > node.**js内でアクセスされたURL引数をJSONに変換してクライア**ントへsocket-ioにて一斉配信しています。
>>>> >> >
>>>> >> >
>>>> >> > とりあえず動いてはいるのですが、**URLで受け取ったデータをsocket-ioにて配信する際、**一度、自分自身のsocket-*
>>>> *ioにconnectしてsocketにセットしています。
>>>> >> >
>>>> >> > connectが非同期となる為setTimeoutを利用して**いる為、サーバの負荷次第ではconnect処理(**
>>>> serversocket1)を配信処理(**serversocket2)**が追い越してしまうと考えています。
>>>> >> >
>>>> >> > 何か良い制御方法は無いのでしょうか?
>>>> >> >
>>>> >> > よろしくお願いします。
>>>> >> >
>>>> >> > 環境
>>>> >> > windows2003 sp2
>>>> >> > node v0.8.17
>>>> >> >
>>>> >> >
>>>> >> > メイン部分のソースです。
>>>> >> >
>>>> >> > ------------------------------**------------------------------**
>>>> ------------------------------**-
>>>> >> > var http = require("http");
>>>> >> > var url = require("url");
>>>> >> >
>>>> >> > var socketval = 0;
>>>> >> >
>>>> >> >
>>>> >> > function start(route,handle){
>>>> >> >     var query = "";
>>>> >> >     function onRequest(request,response){
>>>> >> >         var queryData = url.parse(request.url, true).query;
>>>> >> >         var url_parts = url.parse(request.url,true);
>>>> >> >         query = url.parse(request.url, true).query;
>>>> >> >         var pathname = url.parse(request.url).**pathname;
>>>> >> >         if(socketval===0){
>>>> >> >             setTimeout(function(){**serversocket1("Appname",query)
>>>> **},1);
>>>> >> >         };
>>>> >> >
>>>> >> >             setTimeout(function(){**serversocket2("Appname",query)
>>>> **},1000);
>>>> >> >         request.setEncoding("utf8");
>>>> >> >
>>>> >> >         request.addListener("end",**function(){
>>>> >> >             route(handle,pathname,**response);
>>>> >> >         });
>>>> >> >     }
>>>> >> >
>>>> >> >     var server = http.createServer(onRequest).**listen(8080);
>>>> >> >     //console.log("Serevr has sterted.");
>>>> >> >
>>>> >> >     // socket.io
>>>> >> >     var io = require('socket.io').listen(**server);
>>>> >> >
>>>> >> >
>>>> >> >     var archiveMessages = {};
>>>> >> >     var channels = ['Appname'];
>>>> >> >
>>>> >> >     var appname = io.of('/appname');
>>>> >> >     var socket = "";
>>>> >> >     var socket_c = "";
>>>> >> >     appname.on('connection', function(socketin){
>>>> >> >         console.log('connected: %s', socket.id);
>>>> >> >         socket = socketin;
>>>> >> >
>>>> >> >         // push available channel list
>>>> >> >         socket.emit('available_**channel', channels);
>>>> >> >
>>>> >> >         socket.on('join', function(value){
>>>> >> >             console.log('%s joined channel: %s', socket.id,
>>>> >> > value.channelId);
>>>> >> >
>>>> >> >             socket.join(value.channelId);
>>>> >> >         });
>>>> >> >         socket.on('join_c', function(value){
>>>> >> >             console.log('clientjoin %s joined channel: %s',
>>>> socket.id,
>>>> >> > value.channelId);
>>>> >> >
>>>> >> >             socket.join(value.channelId);
>>>> >> >             socket_c = socket;
>>>> >> >             socketval=1;
>>>> >> >         });
>>>> >> >
>>>> >> >         socket.on('post', function(message){
>>>> >> >             socket.get('channel_id', function(err, channelId){
>>>> >> >                 console.log(' %s says<%s channel>: %s', socket.id,
>>>>
>>>> >> > channelId, message);
>>>> >> >
>>>> >> >             });
>>>> >> >         });
>>>> >> >
>>>> >> >         socket.on('disconnect', function(){
>>>> >> >             console.log('%s disconnected', socket.id);
>>>> >> >             socket.get('channel_id', function(channelId){
>>>> >> >                 socket.leave(channelId);
>>>> >> >             });
>>>> >> >         });
>>>> >> >
>>>> >> >     });
>>>> >> >
>>>> >> >     var io_c = require('socket.io').client;
>>>> >> >     var appname_c = "";
>>>> >> >     function serversocket1(channelId,data){
>>>> >> >         var appname_c_1 = io_c.connect('http://**localhost:8080');
>>>>
>>>> >> >         appname_c = appname_c_1.of('/appname');
>>>> >> >
>>>> >> >         appname_c.emit('join_c', {
>>>> >> >           channelId: 'Appname'
>>>> >> >         });
>>>> >> >
>>>> >> >     }
>>>> >> >     function serversocket2(channelId,data){
>>>> >> >         socket_c.set('channel_id', channelId, function(){
>>>> >> >           socket_c.emit('posted', data);
>>>> >> >           socket_c.broadcast.to(**channelId).emit('user:message'**,
>>>> data);
>>>> >> >         });
>>>> >> >     }
>>>> >> > };
>>>> >> >
>>>> >> > exports.start = start;
>>>> >> >
>>>> >> > ------------------------------**------------------------------**
>>>> ------------------------------**------
>>>> >> >
>>>> >> >
>>>> >> >
>>>> >> > --
>>>> >> >
>>>> >> >
>>>> >> >
>>>> >
>>>> > --
>>>> >
>>>> >
>>>> >
>>>>
>>>  --
>
>
>
>

-- 



メールによる返信