Bagikan melalui


Tutorial: Membuat aplikasi real-time frekuensi tinggi dengan SignalR 2

Tutorial ini menunjukkan cara membuat aplikasi web yang menggunakan ASP.NET SignalR 2 untuk menyediakan fungsionalitas olahpesan frekuensi tinggi. Dalam hal ini, "olahpesan frekuensi tinggi" berarti server mengirim pembaruan pada tingkat tetap. Anda mengirim hingga 10 pesan per detik.

Aplikasi yang Anda buat menampilkan bentuk yang dapat diseret pengguna. Server memperbarui posisi bentuk di semua browser yang tersambung agar sesuai dengan posisi bentuk yang diseret menggunakan pembaruan berwaktu.

Konsep yang diperkenalkan dalam tutorial ini memiliki aplikasi dalam game real-time dan aplikasi simulasi lainnya.

Di tutorial ini, Anda akan:

  • Menyiapkan proyek
  • Membuat aplikasi dasar
  • Memetakan ke hub saat aplikasi dimulai
  • Menambahkan klien
  • Menjalankan aplikasi
  • Menambahkan perulangan klien
  • Menambahkan perulangan server
  • Tambahkan animasi halus

Peringatan

Dokumentasi ini bukan untuk versi terbaru SignalR. Lihatlah ASP.NET Core SignalR.

Prasyarat

Menyiapkan proyek

Di bagian ini, Anda membuat proyek di Visual Studio 2017.

Bagian ini memperlihatkan cara menggunakan Visual Studio 2017 untuk membuat Aplikasi Web ASP.NET kosong dan menambahkan pustaka SignalR dan jQuery.UI.

  1. Di Visual Studio, buat Aplikasi Web ASP.NET.

    Membuat web

  2. Di jendela Aplikasi Web ASP.NET Baru - MoveShapeDemo , biarkan Kosong dipilih dan pilih OK.

  3. Di Penjelajah Solusi, klik kanan proyek dan pilih Tambahkan>Item Baru.

  4. Di Tambahkan Item Baru - MoveShapeDemo, pilihVisual C#>Web>SignalRterinstal> lalu pilih SignalR Hub Class (v2).

  5. Beri nama kelas MoveShapeHub dan tambahkan ke proyek.

    Langkah ini membuat file kelas MoveShapeHub.cs . Secara bersamaan, ia menambahkan sekumpulan file skrip dan referensi perakitan yang mendukung SignalR ke proyek.

  6. Pilih Alat>NuGet Package Manager>Packet Manager Console.

  7. Di Konsol Pengelola Paket, jalankan perintah ini:

    Install-Package jQuery.UI.Combined
    

    Perintah menginstal pustaka UI jQuery. Anda menggunakannya untuk menghidupkan bentuk.

  8. Di Penjelajah Solusi, perluas simpul Skrip.

    Referensi pustaka skrip

    Pustaka skrip untuk jQuery, jQueryUI, dan SignalR terlihat dalam proyek.

Membuat aplikasi dasar

Di bagian ini, Anda membuat aplikasi browser. Aplikasi mengirimkan lokasi bentuk ke server selama setiap peristiwa pemindahan mouse. Server menyiarkan informasi ini ke semua klien lain yang terhubung secara real time. Anda mempelajari selengkapnya tentang aplikasi ini di bagian selanjutnya.

  1. Buka file MoveShapeHub.cs .

  2. Ganti kode dalam file MoveShapeHub.cs dengan kode ini:

    using Microsoft.AspNet.SignalR;
    using Newtonsoft.Json;
    
    namespace MoveShapeDemo
    {
        public class MoveShapeHub : Hub
        {
            public void UpdateModel(ShapeModel clientModel)
            {
                clientModel.LastUpdatedBy = Context.ConnectionId;
                // Update the shape model within our broadcaster
                Clients.AllExcept(clientModel.LastUpdatedBy).updateShape(clientModel);
            }
        }
        public class ShapeModel
        {
            // We declare Left and Top as lowercase with 
            // JsonProperty to sync the client and server models
            [JsonProperty("left")]
            public double Left { get; set; }
            [JsonProperty("top")]
            public double Top { get; set; }
            // We don't want the client to get the "LastUpdatedBy" property
            [JsonIgnore]
            public string LastUpdatedBy { get; set; }
        }
    }
    
  3. Simpan file.

Kelas MoveShapeHub adalah implementasi dari hub SignalR. Seperti dalam tutorial Memulai SignalR , hub memiliki metode yang dipanggil klien secara langsung. Dalam hal ini, klien mengirim objek dengan koordinat X dan Y baru dari bentuk ke server. Koordinat tersebut disiarkan ke semua klien lain yang terhubung. SignalR secara otomatis menserialisasikan objek ini menggunakan JSON.

Aplikasi mengirimkan ShapeModel objek ke klien. Memiliki anggota untuk menyimpan posisi bentuk. Versi objek di server juga memiliki anggota untuk melacak data klien mana yang sedang disimpan. Objek ini mencegah server mengirim data klien kembali ke dirinya sendiri. Anggota ini menggunakan JsonIgnore atribut untuk menjaga aplikasi dari serialisasi data dan mengirimkannya kembali ke klien.

Memetakan ke hub saat aplikasi dimulai

Selanjutnya, Anda menyiapkan pemetaan ke hub saat aplikasi dimulai. Di SignalR 2, menambahkan kelas startup OWIN membuat pemetaan.

  1. Di Penjelajah Solusi, klik kanan proyek dan pilih Tambahkan>Item Baru.

  2. Di Tambahkan Item Baru - MoveShapeDemo pilihVisual C#>Webterinstal> lalu pilih Kelas Startup OWIN.

  3. Beri nama kelas Startup dan pilih OK.

  4. Ganti kode default dalam file Startup.cs dengan kode ini:

    using Microsoft.Owin;
    using Owin;
    
    [assembly: OwinStartup(typeof(MoveShapeDemo.Startup))]
    namespace MoveShapeDemo
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
                app.MapSignalR();
            }
        }
    }
    

Kelas startup OWIN memanggil MapSignalR saat aplikasi menjalankan Configuration metode . Aplikasi menambahkan kelas ke proses startup OWIN menggunakan atribut assembly OwinStartup .

Menambahkan klien

Tambahkan halaman HTML untuk klien.

  1. Di Penjelajah Solusi, klik kanan proyek dan pilih Tambahkan>Halaman HTML.

  2. Beri nama halaman Default dan pilih OK.

  3. Di Penjelajah Solusi, klik kanan Default.html dan pilih Atur sebagai Halaman Mulai.

  4. Ganti kode default dalam file Default.html dengan kode ini:

    <!DOCTYPE html>
    <html>
    <head>
        <title>SignalR MoveShape Demo</title>
        <style>
            #shape {
                width: 100px;
                height: 100px;
                background-color: #FF0000;
            }
        </style>
    </head>
    <body>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery-ui-1.10.4.min.js"></script>
    <script src="Scripts/jquery.signalR-2.1.0.js"></script>
    <script src="/signalr/hubs"></script>
    <script>
     $(function () {
                var moveShapeHub = $.connection.moveShapeHub,
                $shape = $("#shape"),
                shapeModel = {
                    left: 0,
                    top: 0
                };
                moveShapeHub.client.updateShape = function (model) {
                    shapeModel = model;
                    $shape.css({ left: model.left, top: model.top });
                };
                $.connection.hub.start().done(function () {
                    $shape.draggable({
                        drag: function () {
                            shapeModel = $shape.offset();
                            moveShapeHub.server.updateModel(shapeModel);
                        }
                    });
                });
            });
    </script>
        
        <div id="shape" />
    </body>
    </html>
    
  5. Di Penjelajah Solusi, perluas Skrip.

    Pustaka skrip untuk jQuery dan SignalR terlihat dalam proyek.

    Penting

    Manajer paket menginstal versi skrip SignalR yang lebih baru.

  6. Perbarui referensi skrip di blok kode agar sesuai dengan versi file skrip dalam proyek.

Kode HTML dan JavaScript ini membuat warna merah div yang disebut shape. Ini memungkinkan perilaku penyeretan bentuk menggunakan pustaka jQuery dan menggunakan drag peristiwa untuk mengirim posisi bentuk ke server.

Menjalankan aplikasi

Anda dapat menjalankan aplikasi untuk se'e itu berfungsi. Saat Anda menyeret bentuk di sekitar jendela browser, bentuk juga berpindah di browser lain.

  1. Di toolbar, aktifkan Debugging Skrip lalu pilih tombol putar untuk menjalankan aplikasi dalam mode Debug.

    Cuplikan layar pengguna mengaktifkan mode penelusuran kesalahan dan memilih putar.

    Jendela browser terbuka dengan bentuk merah di sudut kanan atas.

  2. Salin URL halaman.

  3. Buka browser lain dan tempelkan URL ke bilah alamat.

  4. Seret bentuk di salah satu jendela browser. Bentuk di jendela browser lain mengikuti.

Meskipun aplikasi berfungsi menggunakan metode ini, ini bukan model pemrograman yang direkomendasikan. Tidak ada batas atas jumlah pesan yang dikirim. Akibatnya, klien dan server kewalahan dengan pesan dan penurunan performa. Selain itu, aplikasi menampilkan animasi yang terputus-putus pada klien. Animasi dendeng ini terjadi karena bentuk bergerak langsung oleh setiap metode. Lebih baik jika bentuk bergerak dengan lancar ke setiap lokasi baru. Selanjutnya, Anda mempelajari cara memperbaiki masalah tersebut.

Menambahkan perulangan klien

Mengirim lokasi bentuk pada setiap peristiwa pemindahan mouse menciptakan jumlah lalu lintas jaringan yang tidak perlu. Aplikasi ini perlu membatasi pesan dari klien.

Gunakan fungsi javascript setInterval untuk menyiapkan perulangan yang mengirim informasi posisi baru ke server dengan tarif tetap. Perulangan ini adalah representasi dasar dari "perulangan game." Ini adalah fungsi yang berulang kali disebut yang mendorong semua fungsionalitas game.

  1. Ganti kode klien dalam file Default.html dengan kode ini:

    <!DOCTYPE html>
    <html>
    <head>
    <title>SignalR MoveShape Demo</title>
    <style>
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    </style>
    </head>
    <body>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery-ui-1.10.4.min.js"></script>
    <script src="Scripts/jquery.signalR-2.1.0.js"></script>
    <script src="/signalr/hubs"></script>
    <script>
        $(function () {
            var moveShapeHub = $.connection.moveShapeHub,
                $shape = $("#shape"),
                // Send a maximum of 10 messages per second 
                // (mouse movements trigger a lot of messages)
                messageFrequency = 10, 
                // Determine how often to send messages in
                // time to abide by the messageFrequency
                updateRate = 1000 / messageFrequency, 
                shapeModel = {
                    left: 0,
                    top: 0
                },
                moved = false;
            moveShapeHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        moved = true;
                    }
                });
                // Start the client side server update interval
                setInterval(updateServerModel, updateRate);
            });
            function updateServerModel() {
                // Only update server if we have a new movement
                if (moved) {
                    moveShapeHub.server.updateModel(shapeModel);
                    moved = false;
                }
            }
        });
    </script>
       
    <div id="shape" />
    </body>
    </html>
    

    Penting

    Anda harus mengganti referensi skrip lagi. Mereka harus cocok dengan versi skrip dalam proyek.

    Kode baru ini menambahkan updateServerModel fungsi . Ini akan dipanggil pada frekuensi tetap. Fungsi mengirimkan data posisi ke server setiap kali moved bendera menunjukkan bahwa ada data posisi baru untuk dikirim.

  2. Pilih tombol putar untuk memulai aplikasi

  3. Salin URL halaman.

  4. Buka browser lain dan tempelkan URL ke bilah alamat.

  5. Seret bentuk di salah satu jendela browser. Bentuk di jendela browser lain mengikuti.

Karena aplikasi membatasi jumlah pesan yang dikirim ke server, animasi tidak akan muncul sehalus yang dilakukan pada awalnya.

Menambahkan perulangan server

Dalam aplikasi saat ini, pesan yang dikirim dari server ke klien keluar sesering yang diterima. Lalu lintas jaringan ini menghadirkan masalah serupa seperti yang kita lihat pada klien.

Aplikasi ini dapat mengirim pesan lebih sering daripada yang diperlukan. Koneksi dapat menjadi banjir sebagai akibatnya. Bagian ini menjelaskan cara memperbarui server untuk menambahkan timer yang membatasi laju pesan keluar.

  1. Ganti isi MoveShapeHub.cs dengan kode ini:

    using System;
    using System.Threading;
    using Microsoft.AspNet.SignalR;
    using Newtonsoft.Json;
    
    namespace MoveShapeDemo
    {
        public class Broadcaster
        {
            private readonly static Lazy<Broadcaster> _instance = 
                new Lazy<Broadcaster>(() => new Broadcaster());
            // We're going to broadcast to all clients a maximum of 25 times per second
            private readonly TimeSpan BroadcastInterval = 
                TimeSpan.FromMilliseconds(40); 
            private readonly IHubContext _hubContext;
            private Timer _broadcastLoop;
            private ShapeModel _model;
            private bool _modelUpdated;
            public Broadcaster()
            {
                // Save our hub context so we can easily use it 
                // to send to its connected clients
                _hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
                _model = new ShapeModel();
                _modelUpdated = false;
                // Start the broadcast loop
                _broadcastLoop = new Timer(
                    BroadcastShape, 
                    null, 
                    BroadcastInterval, 
                    BroadcastInterval);
            }
            public void BroadcastShape(object state)
            {
                // No need to send anything if our model hasn't changed
                if (_modelUpdated)
                {
                    // This is how we can access the Clients property 
                    // in a static hub method or outside of the hub entirely
                    _hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
                    _modelUpdated = false;
                }
            }
            public void UpdateShape(ShapeModel clientModel)
            {
                _model = clientModel;
                _modelUpdated = true;
            }
            public static Broadcaster Instance
            {
                get
                {
                    return _instance.Value;
                }
            }
        }
            
        public class MoveShapeHub : Hub
        {
            // Is set via the constructor on each creation
            private Broadcaster _broadcaster;
            public MoveShapeHub()
                : this(Broadcaster.Instance)
            {
            }
            public MoveShapeHub(Broadcaster broadcaster)
            {
                _broadcaster = broadcaster;
            }
            public void UpdateModel(ShapeModel clientModel)
            {
                clientModel.LastUpdatedBy = Context.ConnectionId;
                // Update the shape model within our broadcaster
                _broadcaster.UpdateShape(clientModel);
            }
        }
        public class ShapeModel
        {
            // We declare Left and Top as lowercase with 
            // JsonProperty to sync the client and server models
            [JsonProperty("left")]
            public double Left { get; set; }
            [JsonProperty("top")]
            public double Top { get; set; }
            // We don't want the client to get the "LastUpdatedBy" property
            [JsonIgnore]
            public string LastUpdatedBy { get; set; }
        }
        
    }
    
  2. Pilih tombol putar untuk memulai aplikasi.

  3. Salin URL halaman.

  4. Buka browser lain dan tempelkan URL ke bilah alamat.

  5. Seret bentuk di salah satu jendela browser.

Kode ini memperluas klien untuk menambahkan Broadcaster kelas. Kelas baru membatasi pesan keluar menggunakan Timer kelas dari kerangka kerja .NET.

Ada baiknya untuk mempelajari bahwa hub itu sendiri bersifat transitory. Ini dibuat setiap kali diperlukan. Jadi aplikasi membuat Broadcaster sebagai singleton. Ini menggunakan inisialisasi malas untuk menunda Broadcasterpembuatan hingga diperlukan. Itu menjamin bahwa aplikasi membuat instans hub pertama sepenuhnya sebelum memulai timer.

Panggilan ke fungsi klien UpdateShape kemudian dipindahkan dari metode hub UpdateModel . Ini tidak lagi dipanggil segera setiap kali aplikasi menerima pesan masuk. Sebagai gantinya, aplikasi mengirim pesan ke klien dengan tarif 25 panggilan per detik. Proses ini dikelola oleh timer _broadcastLoop dari dalam Broadcaster kelas .

Terakhir, alih-alih memanggil metode klien dari hub secara langsung, Broadcaster kelas perlu mendapatkan referensi ke hub yang saat ini beroperasi _hubContext . Ini mendapatkan referensi dengan GlobalHost.

Tambahkan animasi halus

Aplikasi hampir selesai, tetapi kita bisa melakukan satu perbaikan lagi. Aplikasi memindahkan bentuk pada klien sebagai respons terhadap pesan server. Alih-alih mengatur posisi bentuk ke lokasi baru yang diberikan oleh server, gunakan fungsi pustaka animate UI JQuery. Ini dapat memindahkan bentuk dengan halus antara posisinya saat ini dan baru.

  1. Perbarui metode klien updateShape dalam file Default.html agar terlihat seperti kode yang disorot:

    <!DOCTYPE html>
    <html>
    <head>
        <title>SignalR MoveShape Demo</title>
        <style>
            #shape {
                width: 100px;
                height: 100px;
                background-color: #FF0000;
            }
        </style>
    </head>
    <body>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery-ui-1.10.4.min.js"></script>
    <script src="Scripts/jquery.signalR-2.1.0.js"></script>
    <script src="/signalr/hubs"></script>
    <script>
            $(function () {
                var moveShapeHub = $.connection.moveShapeHub,
                    $shape = $("#shape"),
                    // Send a maximum of 10 messages per second 
                    // (mouse movements trigger a lot of messages)
                    messageFrequency = 10, 
                    // Determine how often to send messages in
                    // time to abide by the messageFrequency
                    updateRate = 1000 / messageFrequency, 
                    shapeModel = {
                        left: 0,
                        top: 0
                    },
                    moved = false;
                moveShapeHub.client.updateShape = function (model) {
                     shapeModel = model;
                     // Gradually move the shape towards the new location (interpolate)
                     // The updateRate is used as the duration because by the time 
                     // we get to the next location we want to be at the "last" location
                     // We also clear the animation queue so that we start a new 
                     // animation and don't lag behind.
                     $shape.animate(shapeModel, { duration: updateRate, queue: false });
                };
                $.connection.hub.start().done(function () {
                    $shape.draggable({
                        drag: function () {
                            shapeModel = $shape.offset();
                            moved = true;
                        }
                    });
                    // Start the client side server update interval
                    setInterval(updateServerModel, updateRate);
                });
                function updateServerModel() {
                    // Only update server if we have a new movement
                    if (moved) {
                        moveShapeHub.server.updateModel(shapeModel);
                        moved = false;
                    }
                }
            });
    </script>
       
        <div id="shape" />
    </body>
    </html>
    
  2. Pilih tombol putar untuk memulai aplikasi.

  3. Salin URL halaman.

  4. Buka browser lain dan tempelkan URL ke bilah alamat.

  5. Seret bentuk di salah satu jendela browser.

Gerakan bentuk di jendela lain tampak kurang dendeng. Aplikasi ini menginterpolasi pergerakannya dari waktu ke waktu daripada diatur sekali per pesan masuk.

Kode ini memindahkan bentuk dari lokasi lama ke yang baru. Server memberikan posisi bentuk selama interval animasi. Dalam hal ini, itu 100 milidetik. Aplikasi menghapus animasi sebelumnya yang berjalan pada bentuk sebelum animasi baru dimulai.

Mendapatkan kode

Unduh Proyek yang Selesai

Sumber Daya Tambahan:

Paradigma komunikasi yang baru saja Anda pelajari berguna untuk mengembangkan game online dan simulasi lainnya, seperti game ShootR yang dibuat dengan SignalR.

Untuk informasi selengkapnya tentang SignalR, lihat sumber daya berikut ini:

Langkah berikutnya

Di tutorial ini, Anda akan:

  • Menyiapkan proyek
  • Membuat aplikasi dasar
  • Dipetakan ke hub saat aplikasi dimulai
  • Menambahkan klien
  • Menjalankan aplikasi
  • Menambahkan perulangan klien
  • Menambahkan perulangan server
  • Menambahkan animasi halus

Lanjutkan ke artikel berikutnya untuk mempelajari cara membuat aplikasi web yang menggunakan ASP.NET SignalR 2 untuk menyediakan fungsionalitas siaran server.