ساخت چت روم با PHP و jQuery فناوری Ajax

ساخت چت روم با PHP و jQuery فناوری Ajax

ساخت چت روم با PHP و jQuery – در این آموزش یاد خواهید گرفت که چگونه یک چت روم نیمه حرفه ای با استفاده از PHP و جی کوئری بسازید که از فناوری Ajax بهره می برد .

در این آموزش از :
1- PHP برای مدیریت درخواست ها در سمت سرور استفاده می کنیم
2- MYSQL برای ذخیره اطلاعات کاربر استفاده می کنیم
3- Javascript (jQuery) برای ارسال درخواست Ajax و تجربه یک برنامه SPA استفاده می کنیم .

2 بخش اصلی یعنی :

فایل app.js که برای ارسال درخواست و مدیریت سمت کلاینت است .
فایل process.php که برای مدیریت درخواست های ارسال شده کاربر می باشد مثل : ارسال پیام ، دریافت پیام


فایل app.js مدیریت سمت کلاینت با Javascript

ابتدا ارتفاع پنجره چت را متناسب با صفحه دستگاه تنظیم می کنید سپس با استفاده از متد Head درخواستی را می فرستیم که آیا پیام جدید برای کاربری فعلی وجود دارد یا خیر .

در صورتی که وجود نداشت status code 304 دریافت می کنیم ، اگر وجود داشت 200 دریافت می کنیم و مجدد این بار درخواست GET می فرستیم . این روند هر 2.5 ثانیه اجرا می شود تا اطلاعات را بروزرسانی کند .

همچنین برای ارسال پیام در صورتی که کاربر پیام را در keypad وارد کرده بود ، خالی نبود و دکمه ارسال را زد پیام را می فرستد ، البته در سمت سرور بررسی می شود که پیام ارسال شده برای کاربر دیگر (کاربر وجود دارد) .

$(document).ready(function() {

    let userMessageList = JSON.stringify({});
    let users = undefined;

    let requestCounter = 0;
    let oldLength = -1;


    const chatroomDOM = $('.chatroom');
    const messageViewDOM = $('#message-view');
    const keypadWrapperDOM = $('.keypad-wrapper');
    const sendMessageBtnDOM = keypadWrapperDOM.find("button");
    const keypadDom = keypadWrapperDOM.find("#keypad");
    const sendToDOM = keypadWrapperDOM.find("#send_to");

    const WH = window.innerHeight;
    const chatroomHeight = WH - 187;
    const httpURL = location.origin;


    // set default propery
    chatroomDOM.css("height", chatroomHeight + "px");
    chatroomDOM.find(".list-contact-wrapper,.message-view-wrapper").css("height", chatroomHeight + "px");


    sendMessageBtnDOM.click(sendMessageBtnHandler);

    // helper functions

    function helperTimestampToReadableTime(time) {
        const d = new Date();

        d.setTime(time * 1000);

        const year = d.getFullYear(),
            month = d.getMonth() + 1,
            day = d.getDate(),
            hour = d.getHours(),
            minute = d.getMinutes(),
            seconds = d.getSeconds();

        const readableTime = year + "/" + month + "/" + day + " | " + hour + ":" + minute + ":" + seconds;

        return readableTime;
    }

    function helperMessageViewReset() {
        messageViewDOM.html("");
    }

    function helperMessageViewDynamicContent() {
        if (sendToDOM.val() != "") {
            helperMessageViewReset();
            listMessagesOnChatroom(sendToDOM.val());
        }
    }


    // *********** chat ajax request ***********

    function addNewOwnMessageToMessageView(e) {
        const timestampSent = e.time_sent;
        const userRoom = sendToDOM.val();


        if (timestampSent) {
            const messageObject = {
                unique_user: 1,
                from_user: 2,
                timestamp_sent: timestampSent,
                message: keypadDom.val()
            }

            userMessageList = JSON.parse(userMessageList);
            userMessageList[userRoom].push(messageObject);
            userMessageList = JSON.stringify(userMessageList);

            listMessagesOnChatroom(userRoom)

            keypadDom.val("");


        }

    }

    function removeUnreadUserMessage(e) {

        if (e.user_room == "") return;
        const user = e.user_room;

        $(`[data-username=${user}]`).find("#contact-number-message").text("پیام جدیدی وجود ندارد");
    }

    function updateSeenUser() {
        getDataChat({ state: "snd_msg_state", from_user: sendToDOM.val() }, removeUnreadUserMessage, false);
    }

    function listMessagesOnChatroom(userRoom) {
        userMessageList = JSON.parse(userMessageList);
        const userMessages = userMessageList[userRoom];

        userMessageList = JSON.stringify(userMessageList);

        let counter = 0;
        helperMessageViewReset();
        for (const message of userMessages) {
            const messageDetails = {};
            counter++;
            messageDetails.who = message.unique_user != message.from_user ? "owner" : "other";
            messageDetails.number = counter;
            messageDetails.time = helperTimestampToReadableTime(message.timestamp_sent);
            messageDetails.content = message.message;
            generateMessageBox(messageDetails);
        }

        const currentLength = userMessages.length;
        if(oldLength == -1 || oldLength != currentLength){
        oldLength = currentLength;
        updateSeenUser();
        }

    }

    function addUserUnreadMessagesToList(e) {

        if (e === undefined) return;

        const messageList = e;

        for (const message of messageList) {
            const uniqueUname = message["unique_user"];
            userMessageList = JSON.parse(userMessageList);
            let oldMessage = userMessageList[uniqueUname];
            oldMessage = oldMessage[oldMessage.length - 1];
            const newMessage = message;


            if (oldMessage === undefined || oldMessage.timestamp_sent != newMessage.timestamp_sent) {
                
                userMessageList[uniqueUname].push(message);
            }

            userMessageList = JSON.stringify(userMessageList);
        }



    }


    function addUserUnreadMessagesElements(e) {
        if (e === undefined) return;

        const user = e['from_user'];

        const messageNumber = e['countMessage'];

        const msg = messageNumber == 0 ? "پیام جدیدی وجود ندارد" : messageNumber + " پیام جدید";


        $(`[data-username=${user}]`).find("#contact-number-message").text(msg)

    }



    function getUserUnreadMessages() {

    	

        for (const user of users) {
            const userName = user.username;

            requestCounter++;

            getDataChat({ state: "rcv_msg", from: userName, count: true }, addUserUnreadMessagesElements, false);


            if (requestCounter == 1)
                getDataChat({ state: "rcv_msg", from: userName, all_msg_unique: true }, addUserUnreadMessagesToList, false);
            else {
                getDataChat({ state: "rcv_msg", from: userName }, addUserUnreadMessagesToList, false);
                helperMessageViewDynamicContent();
            }
        }
    }


    getDataChat({ state: "rcv_usr" }, userRcvHandler, false);

    function userRcvHandler(e) {
        users = e;
        let counter = 1;

        for (const user of users) {
            const userName = user.username;
            userMessageList = JSON.parse(userMessageList);
            userMessageList[userName] = [];
            userMessageList = JSON.stringify(userMessageList);
            $("#list-contact").append(`
${user.fullname}پیام جدیدی وجود ندارد
`); counter++; } getUserUnreadMessages(); setInterval(getUserUnreadMessages, 2500); } function getDataChat(query, cbk, loop = false) { const queryString = jQuery.param(query); $.ajax({ type: "head", url: httpURL + "/process.php", data: queryString, dataType: "json", complete: function(e) { if (200 <= e.status < 300) { $.get({ url: httpURL + "/process.php", data: queryString, dataType: "json", success: cbk, complete: function(e) { if (loop) setTimeout(getDataChat, 2000, query, cbk, loop); } }); } else { if (loop) setTimeout(getDataChat, 2000, query, cbk, loop); } } }); } // *********** dom event *********** $(document).on("click", ".contact-box", contactHandler); function contactHandler(e) { const thisElement = $(this); const sendToUser = thisElement.data("username"); $('.contact-box').removeClass("active"); thisElement.addClass("active"); if (sendToUser !== undefined) { oldLength = -1; keypadWrapperDOM.removeClass("ds-none"); sendToDOM.val(sendToUser); helperMessageViewDynamicContent(); } } function sendMessageBtnHandler() { const thisElement = $(this); const message = keypadDom.val(); const sendToUser = sendToDOM.val() if (message != "" && sendToUser != "") { getDataChat({ state: "snd_msg", to_user: sendToUser, msg: message }, addNewOwnMessageToMessageView, false); } } function generateMessageBox(messageDetails) { messageViewDOM.append(`
${messageDetails.content} ${messageDetails.time}
`); } });


فایل process.php مدیریت سمت سرور با PHP

در ابتدا کوکی کاربر را اعتبارسنجی می کنیم که آیا امکان دسترسی دارد یا خیر .

به طور کلی سمت سرور را با استفاده از Query String کنترل می کنیم :

state برای دریافت نوع ارسال داده ها است اگر باشد :
rcv_msg پیام های کاربر را دریافت می کند
rcv_msg_unread یعنی کاربر قرار است پیام های خوانده نشده را دریافت کند
snd_msg یعنی کاربر پیامی را می خواهد ارسال کند
snd_msg_state زمانی که کاربر پیام را خواند آن را بروزرسانی کند به خوانده شده
rcv_usr برای لیست کردن تمامی کاربران در چت روم

header("Content-Type: application/json");

if (!empty($_COOKIE['username'])) {

	require_once "define.php";
	require_once ABSPATH . "inc" . DSPR . "class-loader.php";
	$db = new DB();
	$uname = $_COOKIE['username'];

	$get_data = $_GET;
	$state = !empty($get_data["state"]) ? $get_data["state"] : "";
	$from_user = !empty($get_data["from"]) ? $get_data["from"] : "";

	if ($state == "rcv_msg" && !empty($from_user)) {

		$all_msg_unique = !empty($get_data["all_msg_unique"]) ? $get_data["all_msg_unique"] : "";

		if ($all_msg_unique === "true") {
			$user_messages = $db->row_select(['table' => 'message_repo', 'content' => "((`to_usr`=? AND `from_usr`=?) OR (`to_usr`=? AND `from_usr`=?)) ORDER BY `id` ASC", "types" => "ssss", "values" => [$uname, $from_user, $from_user, $uname]]);
		} else {

			$user_messages = $db->row_select(['table' => 'message_repo', 'content' => "`to_usr`=? AND `from_usr`=? AND `seen`=? ORDER BY `id` ASC", "types" => "sss", "values" => [$uname, $from_user, 0]]);
		}

		if (!$user_messages) {

			header("HTTP/1.0 304 Not Modified", true);
		}

		if (!empty($get_data['count']) && $get_data['count'] === "true") {
			$sanitized_messages = ["countMessage" => count($user_messages), "from_user" => $from_user];
		} else {
			$sanitized_messages = [];
			foreach ($user_messages as $user_message) {
				$sanitized_messages[] = [
					'unique_user' => $from_user,
					'from_user' => $user_message['from_usr'],
					'from_user_fullname' => $user_message['from_usr_name'],
					'to_user' => $user_message['to_usr'],
					'message' => $user_message['message'],
					'timestamp_sent' => $user_message['timestamp_sent'],
				];
			}

		}

		echo json_encode($sanitized_messages);

	} elseif ($state == "rcv_msg_unread") {

		$user_messages = $db->row_select(['table' => 'message_repo', 'content' => "`to_usr`=? AND `seen`=? ORDER BY `id` ASC", "types" => "ss", "values" => [$uname, 0]]);

		if (!$user_messages) {

			header("HTTP/1.0 304 Not Modified", true);
		}

		if (!empty($get_data['count']) && $get_data['count'] === "true") {
			$sanitized_messages = ["countMessage" => count($user_messages), "from_user" => $from_user];
		} else {
			$sanitized_messages = [];
			foreach ($user_messages as $user_message) {
				$sanitized_messages[] = [
					'unique_user' => $user_message['from_usr'],
					'from_user' => $user_message['from_usr'],
					'from_user_fullname' => $user_message['from_usr_name'],
					'to_user' => $user_message['to_usr'],
					'message' => $user_message['message'],
					'timestamp_sent' => $user_message['timestamp_sent'],
				];
			}

		}

		echo json_encode($sanitized_messages);

	} else if ($state == "snd_msg" && $_SERVER['REQUEST_METHOD'] != "HEAD") {
		if (isset($get_data['to_user']) && $get_data['to_user'] !== $uname && isset($get_data['msg'])) {
			$user_exist = $db->row_exist(['table' => 'users', 'content' => "username=?", "types" => "s", "values" => [$get_data['to_user']]]);
			if ($user_exist) {
				$time = time();
				Helper::verify_user_by_session();
				$user_fullname = $GLOBALS['current_user']['fullname'];
				$res = $db->row_insert([
					'table' => 'message_repo',
					'content' => "(`from_usr`, `from_usr_name` , `to_usr` , `message` , `timestamp_sent` , `timestamp_seen`) VALUES (? , ? , ? , ? , ? , ?)",
					"types" => "ssssss",
					"values" => [$uname, $user_fullname, $get_data['to_user'], $get_data['msg'], $time, '0'],
				]);

				echo "{\"time_sent\":\"{$time}\",\"msg\" : \"success\",\"status\" : \"1\"}";

				header("HTTP/1.0 201 Created", true);

			} else {
				header("HTTP/1.0 304 Not Modified", true);
			}

		} else {
			echo '{"msg" : "require complete data" , "status" : "0"}';
		}

	} else if ($state === "snd_msg_state") {
		if (isset($get_data['from_user']) && $get_data['from_user'] !== $uname) {
			$time = time();
			$res = $db->row_update(["table" => "message_repo", "content" => "`seen`=? , `timestamp_seen`=? WHERE `to_usr`=? AND `from_usr`=?", "types" => "ssss", "values" => [1, $time, $uname, $get_data['from_user']]]);

			if ($res) {
				echo "{\"time_sent\":\"{$time}\",\"user_room\" : \"{$get_data['from_user']}\",\"msg\" : \"success\",\"status\" : \"1\"}";
			}

		} else {
			header("HTTP/1.0 304 Not Modified", true);
		}

	} else if ($state === "rcv_usr") {
		$users = $db->row_select(['table' => 'users', 'content' => "`username` != ? AND `verified`=?", "types" => "ss", "values" => [$uname, 1]]);

		if (!$users) {
			header("HTTP/1.0 304 Not Modified", true);
		}

		$sanitized_users = [];
		foreach ($users as $user) {
			$sanitized_messages[] = [
				'username' => $user['username'],
				'fullname' => $user['fullname'],
			];
		}

		echo json_encode($sanitized_messages);
	}

}


دموی پروژه ساخت چت روم با PHP و jQuery

پروژه ساخت چت روم با PHP و jQuery
پروژه چت روم با PHP و jQuery


قبل از اجرای برنامه وارد پوشه chatroom DATABASE to import شده دیتابیس را import کنید


دانلود پروژه ساخت چت روم با PHP و jQuery

ارسال نظر