دانشنامه طراحی و برنامه نویسی تحت وب

آیا می دانید شما می توانید آموزش ، اسکریپت و یا مقاله مورد نظرتان را از ما کاملا رایگان درخواست کنید ؟
        برای درخواست اینجا کلیک کنید
مقالات کلوب

نگاهی مختصر به ساختار چت روم کلوب از دید Client - بخش اول

سید فرزاد سید عربی نژاد | شنبه, ۲۱ ارديبهشت ۱۳۹۲، ۰۴:۵۰ ب.ظ | ۰ نظر

ساختار کلی :

در واقع اکثر و میشه گفت تمام سیستم های گفتگوی متنی آنلاین گروهی یک ساختار واحدی رو دنبال میکنند که شامل :

 - محیطی که کاربر متن خودش رو در اون وارد میکنه (تحت کلاینت)

 - تکه کدی که یک سری پردازش روی این متن انجام میشه (تحت کلاینت)

 - فایل و یا کدی که این پردازش حاصل شده رو به سرور ارسال میکنه (تحت کلاینت)

- سرور که اطلاعات رو گرفته آنلایز و پاسخ میده (تحت سرور)

 - کدی که اطلاعات دریافتی از سرور رو میگیره و برای چاپ آماده میکنه (تحت کلاینت)

 - محیطی که کاربر متن های گفتگو شده رو میبینه (تحت کلاینت)

ما با بخش سرور کاری نداریم چون در حالت عادی اصلا دسترسی نداریم بهش  !

ولی 5 بخش در سیستم کاربر یا همون سیستم ماها پردازش و اجرا میشه ، پس اگه بتونیم سیستم و ساختار اون رو بشناسیم می تونیم یه کارایی باهاش بکنیم !!!!


خوب من این بخش هارو که گفتم رو یکی میرم جلو ببینیم چی میشه :|


• محیطی که کاربر متن خودش رو در اون وارد میکنه

این بخش در محیط گفتگوی کلوب یک جعبه متن هست (textarea) که متن رو دریافت میکنه 

انلایز چت روم کلوب دات کام

کد HTML مربوط به کادر متن :

<textarea class="chatPageV2_containerChatForm_textbox" id="chat_body" onkeyup="base_check_composing()" onkeypress="base_checkEnterKey(event)" style="direction: ltr; height: 48px; overflow: hidden;"></textarea>

اگه دقت کرده باشین این تکه کد یک پارمتر داره به نام onkeypress که وقتی دکمه ای فشار داده بشه تابعی با نام base_checkEnterKey شروع به فعالیت میکنه که این تابع درون فایل جاوااسکریپتی هست به نام base_lib.js که در آدرس زیر میتونید کد های مربوط به اون رو ببینید :

http://static.cloob.com//public/scripts/jabber_new/base_lib.js

از طریق Inspect Element نیز می تونید به کد این صفحه دسترسی داشته باشید و حتی به صورت آنلاین اون رو ویرایش کنید و دوباره اجراش کنید. (این نکته مهمیه ! چون با همین روش خیلی کار ها میشه کرد)


اما کد اون تابع که گفتیم وقتی onkeypress میشه اجرا میشه به این صورته :


function base_checkEnterKey(e){
    var key;
    var shiftKey=false;
    if(window.event){
        key = window.event.keyCode;     //IE
        shiftKey=window.event.shiftKey;
    }else{
        key = e.which;     //firefox
        shiftKey=e.shiftKey;
    }
    if(!shiftKey && key == 13){
        base_send_message();
    }

}

در کد بالا چند شرط ساده رو میشه دید ! ولی چیزی که به درد ما میخوره شرط آخر هست .


شرط به این ترتیبه که میگه وقتی دکمه 13 کیبورد (کد اسکی) فشار داده شد تابع جدیدی به نام base_send_message رو اجرا کن ، که خوشبختانه این تابع تویه همین صفحه base_lib.js هستش.


خوب تا اینجا یه مروری میکنیم > وقتی شما دارین تویه کادر متن تایپ میکنید تابع اولی (onkeypress) بررسی میشه و تا وقتی دکمه اینتر (کد 13) زده نشه هیچ اتفاقی نمی افته تا اینکه شما اینتر رو بزنید و تابع دوم اجرا میشه که این تابع هست : base_send_message


کد این تابع به شکل زیر هست

function base_send_message(){
	var msg_out = c_$('chat_body').value;
	msg_out = strGetTrim(msg_out);

    msg_out = base_limitText(msg_out);


	if(msg_out=='buzz'){
		if(!other_alarmreq[base_active_Receiver_name] && !c_$('chat_body').disabled && base_active_Receiver_type=='chat'){
			other_setBuzz();
		}
		else{
			c_$('chat_body').value='';
			return false;
		}
	}
	
	if(base_active_Receiver_name!='' && msg_out!='' && (base_active_Receiver_type=='chat' || msg_out!='buzz')){
		c_$('chat_body').value = '';
		var content = new Array();
       // msg_out = msg_out.replace("\n",_msg_break_line_split) ;
        msg_out = msg_out.split("\t").join(_msg_break_tab_split);
        msg_out = msg_out.split("\n").join(_msg_break_line_split);
		content['body']= persianUrl.encode(msg_out);
		var rec_type = '';
		var rec_Nickname = '/'+jabber_resource;
		var chatType = 'chat';
		if(base_active_Receiver_type!='chat'){
			var rec_type = base_active_Receiver_type+'.';
			rec_Nickname = '';
			chatType = 'groupchat';
		}
		else{
			content['offline']= true;
		}
		var base_rec = base_active_Receiver_name+'@'+rec_type+jabber_serverName+rec_Nickname ;
		
		var sender = jabber_username+'@'+jabber_serverName+'/'+jabber_resource ;
		var msgid = '';

        var objName = base_active_Receiver_type+__base_split_Type_Name+base_active_Receiver_name;

        if(base_active_Receiver_type=='chat'){
            msgid = chatType + "_" + base_getrandid();
            base_fill_chatbox(sender,base_rec,msg_out,jabber_firstname,jabber_fullname,jabber_userphotoPath,'',msgid);
		}
        else{
            if(!base_clubroom_sendMessage_timer[objName]){
                base_clubroom_sendMessage_timer[objName]=setTimeout(function(){
                    if(base_chatData_Arr_Write[objName]){
                        base_chatData_Arr_Write[objName] = null ;
                        c_$('chat_body').disabled = 1;

                        base_clubroom_sendMessage_timer[objName]= null;
                    }

                },1000);
            }
        }
		

		this_key = base_chatData_Arr_Msg_Key[objName] ;
		base_chatData_composing[objName] = false;

        jabber_SendMessage(base_rec, chatType, msgid, content, '','',this_key);

	}
	c_$('chat_body').value = '';
    setTimeout(function () {
        c_$('chat_body').value = '';
        c_$('chat_body').focus();
    }, 20);
	//c_$('chat_body').focus();
	return false;
}

چند نکته مهم و جالب اینجا هست که فقط به بررسی اونها می پردازم و بقیه کد هایی که اینجا نوشته عملا به درد ما نمیخوره


یکی از این تکه کد ها c_$('chat_body').value این هست ! این تیکه کد در واقع مقداری که شما تویه اون کادر متن تو صفحه نوشتین رو نشون میده ، و چند جا ازش استفاده شده مثلا :

در آخر اون رو خالی کرده (یعنی وقتی متن شما ارسال میشه میبینید که متن تویه کادر پاک میشه) :

 c_$('chat_body').value = '';

در بخش های بالاتر هم کد مربوط به بررسی و ارسال این متن نوشته شده (که بعدا در مورد شرح کامل این بخش تو آنالیز های بعدی خواهم پرداخت) ولی مهمترین بخش این کدها دستور زیر هست که متن نوشته شده رو به یک تابع دیگه به نام  jabber_SendMessage ارسال میکنه 

        jabber_SendMessage(base_rec, chatType, msgid, content, '','',this_key);
(فقط یه چیزی بگم اون جابر منظور اسم جابر نیست بلکه به معنی گپ و گفتگوه :D)

خوب اما این تابع کجا هست ؟ و چه مقدار هایی بهش ارسال میشه ؟؟؟

base_rec :  اولین پارمتری که به داخل این تابع ارسال میشه شماره و یا شناسه چت روم هست ! که با استاندارد زیر ساخته میشه :

شناسه روم@clubroom.jabber.cloob.com
این شناسه روم رو از کجا میشه فهمید ؟؟ خیلی آسون هست بالای هر رومی که برید این شماره نوشته شده برای مثلا : room_26760

انلایز چت روم کلوب دات کام

chatType : این پارامتر مقداری که میگیره نوع صفحه چت شما رو مشخص میکنه ، که آیا این متن مربوط به یک روم عمومی (groupchat) هست یا چت خصوصی (chat)

msgid : پارامتر بعدی یک رشته و عدد ساخته شده توسط خود کلوب هست که به متن شما یک شناسه میده ! که اگه این شناسه رو تکراری هم بزنید مشکلی بوجود نمیاد (این یعنی ضعف امنیتی)


content : مهمترین پارامتر میشه گفت همیه ، که یک آرایه هست (یعنی یه مقدار نیست بلکه چندین مقدار توش قرار داره) که متن اصلی که میخوایم ارسال کنیم به سرور تا به همه نشون بده از درون این آرایه به تابع بعدی (jabber_SendMessage) ارسال میشه


'' ,'' : این پارمتر ها خالی ارسال میشن و تویه چت گروهی استفاده ای نداره ، ولی تویه چت خصوصی دیلوری یا همون تیک سبز کچولو که کنار متن میاد با این ها ارسال میشن


this_key : پارامتر آخر هم یکی از مهم ترین پارمتر های ارسالی هست ، این پارامتر هم کلید روم هست، منظور از کلید در واقع میشه گفت پسورد روم ، که شما در حال عادی نمی بینید اینجوری در نظر بگیرید که پارمتر اولی یوزر و پارمتر آخر پسورد روم هست که به کمک اونا کلوب میفهمه متن باید کدوم روم بره نمایش داده بشه ، برای مثلا یک کلید روم این هست : e94786029126289353dba4aa826f0d59


خوب همه این موارد که پر شدن (که اکثر پارامتر ها توسط خود کلوب پر میشن که قابل ویرایش توسط ما هم هستن ، و یکی که متن ما هست content) آماده ارسال به تابع jabber_SendMessage میشه 


این تابع (jabber_SendMessage) کدهاش مثلا از دید ما پنهان شده اند و در یک فایل جاوااسکریپت دیگه به نام  g.chatroom.new.v4.js قرار داره که این فایل توسط یک سری ساختار کدگذاری شده که نشه فهمید درون این فایل چه اتفاقی می افته ، و من به حق برنامه نویس کلوب احترام میزارم و کل فایل رو دیکود شده اینجا نمی نویسم فقط یه تیکه هاییش رو مینویسم (که اگه خودتون یکم زرنگ باشین دی کودرش رو پیدا میکنید) 

آدرس فایل : 

http://static.cloob.com//public/scripts/jabber_new/g.chatroom.new.v4.js

خوب حالا این پارمتر ها که از تابع قبلی به داخل  jabber_SendMessage که کد شده هست ارسال کردیم چه اتفاقی می افته ؟

کد مربوط به این تابع که من دیکود کردم به شکل زیر است

function jabber_SendMessage(to,type,id,content,payload,composing,cloobkey){
			if(to){
				if(!id){
					id=type+"_"+base_getrandid()
				}
				xml="<message to='"+to+"' type='"+type+"' id='"+id+"'>\n";
				if(content['subject']){
					xml+="<subject>"+content['subject']+"</subject>\n"
				}
				if(content['thread']){
					xml+="<thread>"+content['thread']+"</thread>\n"
				}
				if(composing){
					xml+="<composing>"+composing+"</composing>\n"
				}
				else if(content['body']){
					xml+="<body> "+base_codeSpChars(content['body'])+"</body>\n"
				}
				if(content['offline']){
					xml+="<x xmlns='jabber:x:event'><delivered/></x>\n"
				}
				xml+="<cloobkey>"+cloobkey+"</cloobkey>\n";
				xml+="<firstname>"+jabber_firstname+"</firstname>\n";
				xml+="<fullname>"+jabber_fullname+"</fullname>\n";
				xml+="<photopath>"+jabber_userphotoPath+"</photopath>\n";
				xml+=payload;
				xml+="</message>\n";
				Jabber_AddToLog('send msg : '+xml);
				jabber_sendPacket(xml)
			}
		}

اگه یکم دقیق نگاه کنید کاملا مشخص هست چی به چیه ! اون پارمترها رو که پاس کردیم اینور رو میگره و یک رشته XML تولید میکنه ! 


خوب الان به یک نکته ای میرسیم ! متن و مشخصات ما قبل از ارسال به سرور و نمایش تویه روم به XML تبدیل میشن ! و این خیلی خوبه از نظر کد نویسی و من به برنامه نویسی که اینو نوشته تبریک میگم که XML رو برای ساختار جابجای متن ها انتخاب کرده ، (اگر بخواید بدونید XML چیه ! یه توضیح کوتاه تو همین وبلاگ نوشتم)


خوب برگردیم سر موضوع اصلی بعد از ساخته شدن یه رشته XML ، این رشته به داخل یک تابع دیگه ارسال میشه به نام jabber_sendPacket !!

برای مثال یک رشته XML ایجاد شده توسط کلوب به شکل زیر میشه »

<message to='room_26760@clubroom.jabber.cloob.com' type='groupchat' id='groupchat_6033876b3937314a'>
<body> متن تست</body>
<cloobkey>e9a62906886a5adca7e21287d0fbac11</cloobkey>
<firstname>اربابــــــ</firstname>
<fullname>اربابــــــ</fullname>
<photopath>/public/user_data/user_photo/715/2545741.jpg</photopath>
</message>
رشته XML بالا به تابع jabber_sendPacket  ارسال میشه ! و یک سری اتفاقات مهیج و جالب اونجا انجام میشه ! که من این قسمت هارو برای نگه داشتن ضریب امنیتی روم ها خلاصه وار رد میشم ، ایشاا... چند تا نکته مهم توسط مدیران کلوب رفع میشه و من اون موقع سورس اونهارو هم رو میکنم . خوب بگذریم ...

بعد از آماده شدن رشته بالا ، در تابع jabber_sendPacket  یک سیشن ایجاد میشه و یک پـ ـــــــــــروکـــــ ــــسی که کلوب اسمش رو گذاشته فلش پــــــ ــــروکـــ ــســ ـی فراخوانی میشه ، این فلش ه در واقع تویه همون صفحه چت روم هست ولی دیده نمیشه که 
آدرس اون :
http://www.cloob.com/public/public/images/flashjsproxy/JsSocketProxy_chat_443?84821248
که به آخرش یه SWF اضافه کنید همون فایل فلش هست ، ولی چیزی برای نمایش نداره ، در واقع چند سطر کد داره که اگه دیکامپایلر داشته باشید میتونید بفهمید این کد ها چین که من اینجا میزارمشون . 
این فلش پـــــروکــــــــ ســـــــ ـی فایل XML که آماده شده رو با یک پورت ایمن SSL 443 به سرور مربوط به گفتگو ها ارسال میکنه 

کد اکشن اسکریپت ارتباط با سرور چت کلوب : 
System.security.loadPolicyFile("xmlsocket://chat.cloob.com:443");
var  = new JSP();
و کد اکشن مربوط به دریافت اون XML که از طرف فایل جاوا اسکریپت در سیستم شما ارسال شده :

// Action script...

// [Initial MovieClip Action of sprite 1]
#initclip 1
class JSP
{
    var _eventHandler, _socket;
    function JSP()
    {
        flash.external.ExternalInterface.addCallback("connect", this, connect);
        flash.external.ExternalInterface.addCallback("sendMessage", this, sendMessage);
        flash.external.ExternalInterface.addCallback("disconnect", this, disconnect);
        flash.external.ExternalInterface.addCallback("setEventHandlers", this, setEventHandlers);
        _eventHandler = new Object();
        _socket = new XMLSocket();
        _root.jsP = this;
        _socket.onConnect = function (success)
        {
            _root.jsP.raiseEvent(_root.jsP._eventHandler.on_connect, [success]);
        };
        _socket.onClose = function ()
        {
            _root.jsP.raiseEvent(_root.jsP._eventHandler.on_disconnect, []);
        };
        _socket.onData = function (msg)
        {
            _root.jsP.raiseEvent(_root.jsP._eventHandler.on_message, [msg]);
        };
    } // End of the function
    function connect(host, port)
    {
        var _loc3 = _socket.connect(host, port);
        if (!_loc3)
        {
            var _loc2 = new Object();
            _loc2.type = "connectError";
            this.raiseEvent(_eventHandler.on_error, [_loc2]);
        } // end if
    } // End of the function
    function sendMessage(msg)
    {
        _socket.send(msg);
    } // End of the function
    function disconnect()
    {
        _socket.close();
    } // End of the function
    function setEventHandlers(eventHandlers)
    {
        for (var _loc2 = 0; _loc2 < eventHandlers.length; ++_loc2)
        {
            _eventHandler["on_" + eventHandlers[_loc2].name] = eventHandlers[_loc2].handler;
        } // end of for
    } // End of the function
    function raiseEvent(handlerName, args)
    {
        flash.external.ExternalInterface.call(handlerName, args);
    } // End of the function
} // End of Class
#endinitclip

خوب ! فعلا تا اینجا بسه ، بخش بعدی آنالیز مربوط به این هست که متنی که ارسال شده چطوری وارد صفحه روم ما میشه !

چیزهایی که الان گفتم میشه خیلی کارا کرد ، ولی این مطالب برای استفاده های سودمند تهیه شده (مثل تغییر فونت ، تغییر شکل ظاهری صفحه ، آشنایی و پیدا کردن راه حل های جدید برای مبارزه با برخی مثائل بوجود اومده در روم ها و ...) و مسئولیت استفاده آن به هر نحوی به عهده شخص می باشد.

• یه پلاگین هم به زودی با استفاده از همین ها ارائه خواهم داد که می تونید به کمک اون هر کسی رو که دوست نداشتید متنش رو تویه روم ببینید تمام متن هاش رو بلاک کنید و تویه روم برای شما دیده نشه.

با تشکر از توجه شما اگه غلط املایی یا هر چی بوده ببخشید دیگه :|

  • سید فرزاد سید عربی نژاد

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی