August 27, 2024
Understanding Code-First and Database-First in Entity Framework
When developing applications using Entity Framework (EF), choosing the right approach for designing your database is crucial. The two main strategies are Code-First and Database-First. Each has its strengths and is suitable for different scenarios. Let's delve into the details of these approaches to understand their differences and determine which might be the best fit for your project.
August 9, 2024
Benefits of using Prism + ReactiveProperty in a WPF project
Windows Presentation Foundation (WPF) is a Microsoft platform used to build graphical applications for workstations running the Windows operating system. First introduced in 2006 in the .NET Framework 3.0, WPF offers many improvements over previous Windows Forms, including the ability to build more user-friendly and dynamic user interfaces. It also provides powerful data linking capabilities and supports multimedia such as images, audio and video.
August 9, 2024
.NET - Use Analyze Code Coverage for Unit Testing
Code coverage is a percentage measure of your source is tested. As an example, if you have a small application with only 4 conditional branches of code (branch a, branch b, branch c and branch d), one unit test that verifies conditional branch d will report branch code coverage of 25%.
This article discusses the usage of code coverage for unit testing with Coverlet, a cross platform code coverage library for .NET, with support for line, branch and method coverage.
August 9, 2024
When should you use SCSS?
First of all, let's find out what SCSS is?
SCSS stands for "Sassy CSS", an extension language of CSS (Cascading Style Sheets).
Overall SCSS provides additional features and improvements over traditional CSS, such as variables, nesting rules, mixins, inheritance, and many other features that make writing and managing CSS code easier and more efficient.
June 22, 2024
MVP Design Pattern in iOS programming
1. Model
@interface Student : NSObject@property (nonatomic, strong) NSString *name;@property (nonatomic, assign) NSInteger age;- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;@end@implementation Student- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {self = [super init];if (self) {_name = name;_age = age;}return self;}2. View Protocol
@protocol StudentViewProtocol <NSObject>- (void)showStudentName:(NSString *)name;- (void)showStudentAge:(NSString *)age;@end
3. Presenter
#import "StudentViewProtocol.h"@protocol StudentPresenterProtocol <NSObject>- (void)onLoadStudentButtonClicked;@end@interface StudentPresenter : NSObject <StudentPresenterProtocol>@property (nonatomic, weak) id<StudentViewProtocol> view;- (instancetype)initWithView:(id<StudentViewProtocol>)view;@end#import "StudentPresenter.h"#import "Student.h"@implementation StudentPresenter- (instancetype)initWithView:(id<StudentViewProtocol>)view {self = [super init];if (self) {_view = view;}return self;}- (void)onLoadStudentButtonClicked {// In a real application, you might fetch data from a service or databaseStudent *student = [[Student alloc] initWithName:@"Phuoc Nguyen" age:45];// Format data before sending to the ViewNSString *ageString = [NSString stringWithFormat:@"%ld years old", (long)student.age];// Update the View[self.view showStudentName:student.name];[self.view showStudentAge:ageString];}@end4. View
#import <UIKit/UIKit.h>#import "StudentViewProtocol.h"#import "StudentPresenter.h"@interface StudentViewController : UIViewController <StudentViewProtocol>@property (nonatomic, strong)id<StudentPresenterProtocol> presenter;@property (weak, nonatomic) IBOutlet UILabel *nameLabel;@property (weak, nonatomic) IBOutlet UILabel *ageLabel;@property (weak, nonatomic) IBOutlet UIButton *loadStudentButton;@end
#import "StudentViewController.h"@implementation StudentViewController- (void)viewDidLoad {[super viewDidLoad];self.presenter = [[StudentPresenter alloc] initWithView:self];[self.loadStudentButton addTarget:self.presenter action:@selector(onLoadStudentButtonClicked) forControlEvents:UIControlEventTouchUpInside];}- (void)showStudentName:(NSString *)name {self.nameLabel.text = name;}- {self.ageLabel.text = age;}@endThe class diagram:

June 20, 2024
Setting Up MySQL Master-Slave Replication with Docker.
In today's data management environment, ensuring database availability and scalability is critical. MySQL master-slave replication is a popular technique to achieve this, helping to distribute the workload and enhance system reliability. Combined with Docker, the process of deploying and managing this system becomes easier and more flexible. In this article, we will explore how to set up MySQL master-slave replication using Docker.
What is MySQL Master-Slave Replication?
MySQL master-slave replication is a mechanism in which data from a "master" server is automatically replicated to one or more "slave" servers. This helps distribute read load, enhance resiliency, and provide easier backups.
Setup steps
1. We need to set up the directory structure as follows.

2. Edit my.cnf file information for master and slave.
master/my.cnf
|
[mysqld] [mysql] [client] |
slave/my.cnf
|
[mysqld] [mysql] [client] |
3. Edit docker-compose.yml file information.
|
version: '3'
services:
mysql-master:
image: percona:ps-8.0
volumes:
- ./master/data:/var/lib/mysql
- ./master/my.cnf:/etc/my.cnf
environment:
TZ: Asia/Tokyo
MYSQL_USER: master
MYSQL_PASSWORD: Master123@
MYSQL_ROOT_PASSWORD: Mastermaster123
mysql-slave:
image: percona:ps-8.0
container_name: mysql-slave
volumes:
- ./slave/data:/var/lib/mysql
- ./slave/my.cnf:/etc/my.cnf
environment:
TZ: Asia/Tokyo
MYSQL_USER: slave
MYSQL_PASSWORD: slave123@
MYSQL_ROOT_PASSWORD: slaveslave123
|
4. Start 2 servers:
| docker compose up -d |

5. Wait for the process of building the container to be done successfully.
After that, check the process with the command:
| docker-compose ps |

6. Enter the "mysql-master" container to set the replication DB on the master server:
| docker-compose exec mysql-master bash |

7. Login to mySQL by the root account:
| mysql -u root -pMastermaster123 |

8. Check the binary log whether enabled successfully or not:
| SHOW VARIABLES LIKE 'log_bin'; |

You must make sure the status of the binary is ON before processing the next step.
9. Create a new user in order to the slave server can access to the master server and check the binary log.
Use the below command to create the 'replication' user.
| CREATE USER 'replication'@'%' IDENTIFIED BY 'Slaverepl123'; |

10. Grant user replication access to allow creation for MySQL replications:
| GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%'; |

11. Confirm whether the grants of the user were successful or not:
| SHOW GRANTS FOR replication@'%'; |

12. Confirm the status of the binary log on the master server:
| SHOW MASTER STATUS\G |

You need to save the File and Position.
We will use these values to set on the slave server.
13. Enter the "mysql-slave" container to set the replication DB on the slave server:
| docker-compose exec mysql-slave bash |

14. Login to mySQL by the root account:
| mysql -u root -pslaveslave123 |

15. Execute the SQL command so it can read the binary log for any changes on the master server and make it the same on the slave server.
We will set the value of the MASTER_LOG_FILE and MASTER_LOG_POS by the value obtained from step 12.
| CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='replication', MASTER_PASSWORD='Slaverepl123', MASTER_LOG_FILE='binlog.000003', MASTER_LOG_POS=1161; |

16. Let’s start the slave on mysql:
| START SLAVE; |

17. Confirm the status of the replication on the slave server:
| SHOW SLAVE STATUS\G |

If the Slave_IO_State is "Waiting for source to send event" then we have set up successfully.
From now on, if the master server changes anything, it also changes on the slave server.
18. Confirm synchronization between the two databases.
Check all databases on the master/slave server.
| SHOW DATABASES; |

Create a new database on the master server and re-check all databases on the master server.
| CREATE DATABASE replicate_db; |

A new database has been created on the master server and it has also been created on the slave server.

Conclusion
With the use of Docker, setting up MySQL master-slave replication becomes much simpler and faster. This not only improves data management but also provides an easy environment for testing and development. Try implementing this system for your project to see its obvious benefits.
Using Docker to manage MySQL replication helps you take advantage of the benefits of containerization, such as easily deploying, scaling, and managing complex database systems efficiently.
References:
June 20, 2024
Web Camera Issues on Devices: Troubleshooting Tips
Recently, projects involving device interactions, such as with cameras and audio, have become popular. I just
completed a project using a device's camera, and encountered some challenges that required significant effort to
overcome. To assist with your current or future projects that utilize a device's camera, I decided to write this
blog. It discusses some common issues encountered when working with cameras, and provides solutions to these
problems. I hope this will promptly resolve your current issues and prevent similar problems in your future
projects.
June 19, 2024
What is Socket.IO? Building a real-time chat application with Socket.IO
What is Socket.IO?
The features provided by Socket.IO
-
Real-Time Communication:Socket.IO enables real-time, low-latency communication between clients and servers, allowing for instant data exchange.
-
Bidirectional Data Flow:Both clients and servers can send and receive data simultaneously, enabling interactive and responsive applications.
-
Event-Driven Architecture:Socket.IO uses an event-driven model, where clients and servers can emit and listen for events. This simplifies the handling of real-time interactions.
-
Cross-Platform Compatibility:Socket.IO is compatible with multiple platforms, including web browsers, Node.js servers, and mobile devices. This ensures consistent real-time communication across different environments.
-
Automatic reconnection:Socket.IO automatically handles connection loss and attempts to reconnect the client to the server in the event of lost connection or network problems. This ensures a stable and reliable communication channel.
-
Scalability:Socket.IO supports namespaces and rooms, allowing you to organize and scale real-time communication efficiently. A Namespace is a communication channel that allows you to split the logic of your application over a single shared connection, while rooms enable broadcasting messages to specific groups of clients.
-
Broadcasting:Socket.IO allows you to broadcast messages to all connected clients or to specific groups of clients (rooms). This enables scenarios like sending chat messages to all users in a chat room or notifying specific users about relevant events.
How does Socket.IO work?
-
Sending Messages (Emitting Events):To send a message from the server to the client, you use the emit() method provided by the Socket.IO server library within the context of a connection event. You need to specify the name of the event you want to emit.io.on('connection', (socket) => {// Sending a 'new message' event to the clientsocket.emit('new message', 'Welcome to the chat!');});
-
Receiving Messages (Listening for Events):To receive a message on the client, you listen for the event emitted by the server using the on() method provided by the Socket.IO client library.// Listening for the 'new message' event on the clientsocket.on('new message', (msg) => {console.log('New message received:', msg);});
-
Broadcasting events:Broadcasting events in Socket.IO allows a server to send a message to multiple clients simultaneously. Socket.IO provides several methods for broadcasting events, allowing developers to target specific groups of clients or all connected clients.// Server-side codeio.on('connection', (socket) => {socket.on(new message', (msg) => {// Broadcast to all clients except the sendersocket.broadcast.emit(new message', msg);});});In this example, when a client sends a ‘new message' event, the server broadcasts that message to all connected clients except the one that sent the message.
-
Broadcasting to Specific Rooms:Socket.IO supports the concept of rooms, which allow you to broadcast messages to a subset of clients. A room is simply a named channel that sockets can join and leave.Joining a room: Clients can join a room using the join() method.// Server-side codeio.on('connection', (socket) => {socket.on('join room', (roomName) => {socket.join(roomName);});});Broadcasting to a Room: To broadcast an event to all clients in a specific room, use the to() or in() method.// Server-side codeio.on('connection', (socket) => {socket.on(new message', (roomName, msg) => {// Broadcast to all clients in the specified roomio.to(roomName).emit(new message', msg);
// Broadcast to all clients in room1 and room2io.to('room1').to('room2').emit('chat message', msg);});});
Building a real-time chat application with Socket.IO
-
Initialize a new project:mkdir socketio-chatcd socketio-chatnpm init -y
-
Install Express and Socket.IO:npm install express socket.io
-
Create the server file (index.js):const express = require('express');const http = require('http');const socketIo = require('socket.io');
const app = express();const server = http.createServer(app);const io = socketIo(server);app.use(express.static('public'));
let socketsConected = new Set()io.on('connection', (socket) => {console.log('Socket connected', socket.id)socketsConected.add(socket.id)// Emit 'clients-total' event to clients to display numbers user in the roomio.emit('clients-total', socketsConected.size)
socket.on('disconnect', () => {console.log('Socket disconnected', socket.id)socketsConected.delete(socket.id)io.emit('clients-total', socketsConected.size)})
socket.on('joinRoom', (room) => {// Subscribe the socket to a given channelsocket.join(room);socket.room = room;});
socket.on('chat-message', (data) => {data.sender = socket.id// Broadcast to all clients in the specified roomio.to(socket.room).emit('chat-message', data)})})server.listen(4000, () => console.log(`? server on port 4000`))Explanation: The server is listening for two main events 'joinRoom' and 'chat-message'. The ‘joinRoom’ event will subscribe the socket to a given channel (The room name user selected). The ‘chat-message’ event will listen for the ‘chat-message’ event sent from the client, and then it will send the data to all clients in the specified room via the ‘chat-message’ event.
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>App Chat</title>
</head>
<body>
<div id="app" style="width: 416px;">
<h1 class="title">App Chat ?</h1>
<!-- Join room -->
<div v-if="!joinedRoom" class="join-room d-flex flex-column">
<select v-model="selectedRoom" class="form-select">
<option v-for="room in rooms" :key="room" :value="room">{{ room }}</option>
</select>
<input v-model="nameInput" type="text" class="form-control mt-1 mb-1" placeholder="Please enter name">
<button type="submit" class="btn w-25 btn-light" @click="joinRoom()">Join Room</button>
</div>
<!-- Box chat -->
<div v-else class="main">
<div class="name">
<span class="name-input w-75">{{ selectedRoom }}</span>
<span class="name-input w-25 text-end">{{ clientsTotal }} <i class="far fa-user"></i></span>
</div>
<ul class="message-container" id="message-container" >
</ul>
<form class="message-form" id="message-form">
<inputtype="text"
v-model="messageInput"
class="message-input"
ref="messageInputEl"
/>
<div class="v-divider"></div>
<button type="submit" class="send-button" @click="sendMessage($event)">
send <span><i class="fas fa-paper-plane"></i></span>
</button>
</form>
</div>
</div>
<!-- Include Vue 3 from CDN -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
const {
createApp,
ref,
onMounted
} = Vue;
createApp({
setup() {
const socket = io()
const messageInput = ref('');
const clientsTotal = ref(0)
const nameInput = ref('')
const selectedRoom = ref(null)
const joinedRoom = ref(false)
const socketId = ref(null)
const rooms = ref(['Room 1', 'Room 2', 'Room 3'])
onMounted(() => {
socket.on('connect', () => {
socketId.value = socket.id;
});
});
const sendMessage = async (e) => {
e.preventDefault()
if (messageInput.value === '') return
const data = {
name: nameInput.value,
message: messageInput.value,
dateTime: new Date(),
}
socket.emit('chat-message', data)
addMessageToUI(true, data)
messageInput.value = ''
}
const addMessageToUI = (isOwnMessage, data) => {
const element = `
<li class="${isOwnMessage ? 'message-right' : 'message-left'}">
<p class="message">
${data.message}
<span>${data.name} ● ${moment(data.dateTime).fromNow()}</span>
</p>
</li>`;
const messageContainer = document.getElementById('message-container')
messageContainer.innerHTML += element
}
socket.on('chat-message', (data) => {
if (socketId.value != data.sender) {
addMessageToUI(false, data)
}
})
socket.on('clients-total', (value) => {
clientsTotal.value = value
})
const joinRoom = () => {
joinedRoom.value = true
socket.emit('joinRoom', selectedRoom.value);
}
return {
messageInput,clientsTotal, rooms,
selectedRoom,joinedRoom,nameInput,
sendMessage, joinRoom
};
}
}).mount('#app');
</script>
</body>
</html>
|
Explanation:
- Vue 3 Setup: Use Vue 3 from the CDN to create a simple Vue application.
- Socket.io-client: Include Socket.io-client from the CDN and establish a connection to the server.
- Event Handling: Listen for 'chat-message' and 'clients-total' events from the server to update the message list and number of users in the room. Emit 'joinRoom' and 'chat-message' events to the server.
- Joining Room: Allow users to join a room by emitting a 'joinRoom' event to the server.
- Sending Messages: Allow users to send messages to the room by emitting a 'chat-message' event to the server when the Enter key is pressed.
Demo:
|
Image 1
|
Image 2 |
Conclusion
References
- https://socket.io/docs/v4/
- https://apidog.com/articles/socket-io-vs-websocket/
- https://ably.com/topic/scaling-socketio (image source)
June 19, 2024
NFC and how to use it in the Android Studio Project
NFC stands for Near Field Communication, this is a technology that has emerged as a game changer in mobile application development, providing seamless interaction between devices with just a touch. Among its many capabilities, NFC tag reading stands out as a powerful feature that allows developers to create innovative and user-friendly experiences in their Android apps. In this article, we will explore NFC in detail while also understanding how to read NFC tags in Android Studio
What is NFC?
NFC is a wireless technology that allows data to be transferred between devices over very close distances, usually just a few centimeters. This technology works on the principle of creating an electromagnetic field and communicating through it to transmit data between devices. NFC is commonly used for a variety of purposes, including mobile payments, data exchange, device connectivity, and task automation. In the mobile industry, NFC has become an important technology, especially in creating utility applications and services such as mobile payments, smart cards, and device connectivity. The strength of NFC lies in its convenience, high security, and compatibility with many different types of devices.
The convenience that NFC brings
1. Quick and easy connection:
NFC allows connection between devices simply by bringing them close together without needing to set up or search for devices in Bluetooth or Wi-Fi lists. This reduces the time and complicated steps required to connect, providing a fast and convenient experience for users. We can easily see it through Sony devices, just turn on NFC on the Sony speaker and the Sony phone, and then put them close to each other and they will connect immediately.
2. Mobile payment:
NFC has changed the way payments are made by allowing users to make financial transactions simply by touching or placing their mobile phone near an NFC reader, such as a payment terminal or machine. POS. This creates a quick, convenient, and secure payment process. The most prominent include Google Pay, Samsung Pay, and Apple Pay
3. File and data transfer:
NFC provides a convenient means of transferring files and data between devices without the need for an internet connection. Users can share photos, videos, contacts, or other files simply by touching their phone to another device.
4. Connecting IoT devices (Internet of Things):
NFC provides a simple way to connect IoT devices to each other or to the user's mobile phone. This may include configuring and connecting to devices such as lights, door locks, or other smart control devices.
5. Bluetooth and Wi-Fi connection:
NFC can also be used to initiate a Bluetooth or Wi-Fi connection between devices. Instead of having to search and connect manually, NFC can start this process automatically, reducing inconvenience for users.
How to use NFC in the Android Studio Project
Here's a basic guide to setting up the NFC tag reading in the Android Studio project:
1. Check NFC availability:
Before integrating NFC into your app, ensure that the device is capable of reading NFC and that NFC is enabled. You can do this programmatically using the NfcAdapter class.
2. Add NFC permission and declare NFC feature to Manifest:
Open your app's AndroidManifest.xml file and add the necessary permissions:
3. Define NFC Intent Filter:
Specify intent filters in your manifest to indicate which activities in your app should handle NFC-related actions, such as tag detection, reading, or writing.
For example:
4. Handle Intent in Activity:
In your activity's onCreate() method, handle the NFC intent:
Conclusion
In conclusion, NFC tag reading offers a myriad of benefits for Android app developers, ranging from seamless interaction and information retrieval to authentication and security. By leveraging NFC technology in your Android Studio projects, you can create immersive and intuitive experiences that delight users
[Reference- resource]
- https://developer.android.com/reference/android/nfc/NfcAdapter#summary (Docs)
- https://www.linkedin.com/pulse/how-use-nfc-your-flutter-app-ahmed-ghaith (Image)
June 17, 2024
Understanding Scope in JavaScript
Imagine scope as a boundary within which the identifiers in your JavaScript program: variables and functions.
This boundary delineates their realm of influence, dictating where they can be utilized or even recognized by the rest of your code.

