محسن
3 سال پیش توسط محسن مطرح شد
5 پاسخ

ارسال سوکت با توجه به موقعیت جغرافیایی

سلام.من با لاراول سرویسی دارم که قراره به یه سری راننده با توجه به موقعیت جغرافیایی اطلاعات ارسال کنم(مثل اسنب البته خیلی ساده تر) و از pusher استفاده میکنم.
تو دیتابیس آخرین موقعیت راننده رو دارم(latitude و longitude)
و موقع ثبت درخواست هم موقعیت مبدا رو تو دیتابیس ذخیره میکنم.
حالا میخوام برای راننده هایی که تو شعاع 10 کیلومتری مبدا درخواست هستند اطلاعات پوش بشه.
کدی رو نوشتم اما مطمئن نیستم درست باشه.ممنون میشم راهنمایی کنید.
controller:

 public function create(CreateOrderRequest $request)
    {
        $order = Auth::user()->orders()->create($request->validated());
        $drivers = search for drivers
        foreach ($drivers as $driver) {
            event(new NewOrderRequestEvent($driver,new OrderResource($order)));
        }
        return new OrderResource($order);
    }

event:

class NewOrderRequestEvent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    private $driver_id;
    /**
     * @var Order
     */
    private $order;

    /**
     * Create a new event instance.
     *
     * @param $driver_id
     * @param $order
     */
    public function __construct($driver_id,$order)
    {
        $this->driver_id = $driver_id;
        $this->order = $order;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('new_order_request.' . $this->driver_id.$this->order->id);
    }

    public function broadcastAs()
    {
        return 'new_order_request';
    }

    public function broadcastWith()
    {
        return ['order' => $this->order];
    }

}

و سمت راننده ها:

 // Enable pusher logging - don't include this in production
        Pusher.logToConsole = true;

        var pusher = new Pusher('7b05dfc5160183978e68',
            { authEndpoint: '/broadcasting/auth',
            cluster: 'eu'
        });

        var channel = pusher.subscribe('private-new_order_request.'+{{auth()->id()}});
        channel.bind('private-new_order_request', function(data) {
            console.log(JSON.stringify(data));
        });

channel:

Broadcast::channel('new_order_request.{id}', function ($user, $id) {
    return $user->id==$id;
});

تو این حالت به ازای هر راننده ای که تو موقعیت مناسب باشه یه event اتفاق میافته.درسته این کار؟یا میشه طوری نوشت که فقط یه event به ازای هر درخواست ثبت شه و راننده هایی که در موقعیت مناسب هستن بهشون ارسال شه؟


ثبت پرسش جدید
علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 3 سال پیش مطرح شد
1

اگر با Event ها کار کرده باشی، خیلی تفاوت خاصی نداره
فقط در اینجا اونت ها باید برادکست بشند..

عملکرد پوشر رو تست کردی؟
تغییرات رو در پنل پوشر میتونی دنبال کنی؟

یا میشه طوری نوشت که فقط یه event به ازای هر درخواست ثبت شه و راننده هایی که در موقعیت مناسب هستن بهشون ارسال شه؟

درستش هم همینه.. که به ازای هر درخواست یه اونت فایر بشه
و برای کسانی که تو شعاع ۱۰ کیلومتری هستند، برادکست بشه..


ابتدا ساختار برادکستینگ رو کاملا بررسی کن
اگر همه چیز اوکی باشه، ما باقیش کاری نداره

فقط باید یه کوئری بزنی به دیتابیس و فواصل زیر ۱۰ کیلومتر رو در بیاری
و اونت برای اون کاربر ها برادکست بشه
چیزی شبیه به زیر:


SELECT * FROM (
SELECT *, 
    (
        (
            (
                acos(
                    sin(( $LATITUDE * pi() / 180))
                    *
                    sin(( `latitud_fieldname` * pi() / 180)) + cos(( $LATITUDE * pi() /180 ))
                    *
                    cos(( `latitud_fieldname` * pi() / 180)) * cos((( $LONGITUDE - `longitude_fieldname`) * pi()/180)))
            ) * 180/pi()
        ) * 60 * 1.1515 * 1.609344
    )
as distance FROM `myTable`
) myTable
WHERE distance <= 10
LIMIT 15;

محسن
@mohsenmoradi1851 3 سال پیش آپدیت شد
0

@ali.bayat
ممنون از پاسخ شما.
اگر بخوام ثبت یک درخواست جدید رو به صورت یک event فایر کنم چطور باید تو احراز هویت بررسی کنم؟
مثلا event::

<?php

namespace App\Events;

use App\Models\Order;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class NewOrderRequestEvent implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * @var Order
     */
    private $order;

    /**
     * Create a new event instance.
     *
     * @param $driver_id
     * @param $order
     */
    public function __construct($order)
    {
        $this->order = $order;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('new_order_request');
    }

    public function broadcastAs()
    {
        return 'new_order_request';
    }

    public function broadcastWith()
    {
        return ['order' => $this->order];
    }

}

و channel::

Broadcast::channel('new_order_request', function ($user, $id) {
  // در این قسمت چطور میتونم به درخواست جدید دسترسی داشته باشم تا بخوام با مختصات راننده ها مقایسه کنم؟
});

علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 3 سال پیش مطرح شد
0

مثل Route های معمولی
و از Route Model Binding هم میتونی استفاده کنی
چیزی شبیه به زیر

use App\Models\Order;

Broadcast::channel('new_order_request.{orderId}', function ($user, $orderId) {
return $user->id === Order::findOrNew($orderId)->user_id;
});

اینجوری مشخص میشه که اگر user_id روی درخواست برابر با user فعلی بود
بتونه روی این کانال Listen کنه


محسن
@mohsenmoradi1851 3 سال پیش مطرح شد
0

@ali.bayat
تو این مثال که شما فرمودید داریم به کسی که درخواست رو ایجاد کرده اطلاع میدیم.ولی من میخوام به راننده هایی اطلاع بدم که طبق مختصات جغرافیایی انتخاب میشن.
اگر بخوام event در کانالی مثل

new_order_request.{orderId}

فایر بشه راننده چطور میتونه subscribe کرده باشه در حالی که تازه ایجاد شده؟


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 3 سال پیش مطرح شد
0

من مثالی زدم از مستندات لاراول که شما متوجه لاجیک در این قسمت بشی
مشخصه که شما باید کد رو طبق نیاز پروژه ات ویرایش کنی

مثلا
شما با کوئری که بالاتر فرستادم، راننده هات رو انتخاب کن
میتونی برای هر سفر، به شکل موقتی راننده های نزدیک رو + شماره سفر رو توی یه pivot table ذخیره کنی

و بعد در حین تعریف کانال، چک میکنی اگر اون کاربر جز کاربرهای ذخیره شده در pivot بود
پس میتونه به اون کانال Subscribe کنه


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام